2014-06-24 5 views
15

प्रारंभिक रेल परियोजना पर काम करते हुए, और कोड शैली का विश्लेषण करने के लिए Rubocop का उपयोग करके नेस्टेड कक्षा बनाम कॉम्पैक्ट बनाम। इसने मुझे सवाल उठाने का नेतृत्व किया कि रूबी के घोंसले वर्ग रेल के संदर्भ में कैसे काम करते हैं।रूबी

# app/models/app_core/tenant.rb 
module AppCore 
    class Tenant < ActiveRecord::Base 
    end 
end 

और एक नियंत्रक: उदाहरण के लिए, मेरी इंजन में, मैं एक मॉडल है

# app/controllers/app_core/tenant/members_controller.rb 
module AppCore 
    class Tenant::MembersController < ApplicationController 
    end 
end 

मॉडल के मामले में, मॉड्यूल पथ और वर्ग के नाम के रूप में ही है एक ही है फ़ाइल नाम के रूप में। नियंत्रक मामले में, पथ का दूसरा भाग, "किरायेदार" कक्षा के नाम का हिस्सा है।

Rubocop मुझसे कहता है कि मैं Tenant::MembersController पंक्ति में "कॉम्पैक्ट शैली के बजाय नेस्टेड वर्ग परिभाषाओं का उपयोग करें" है, इसलिए यदि मैं सही ढंग से समझ ...

module AppCore 
    class Tenant 
    class MembersController < ApplicationController 
    end 
    end 
end 

... यह एक फर्क नहीं करना चाहिए ।

अब, मेरा सवाल है कि मेरे पास एक मॉडल के रूप में AppCore :: किरायेदार है, लेकिन फिर AppCore :: किरायेदार को फिर से खोलने लगते हैं और सदस्य नियंत्रक वर्ग को नेस्टेड क्लास के रूप में जोड़ा जाता है। क्या इसका मतलब यह है कि मेरे किरायेदार वर्ग में हमेशा उस घोंसला वाली कक्षा होगी? क्या मुझे अपने मॉडल और नियंत्रक मार्गों को अलग-अलग नाम देने की ज़रूरत है? क्या यह पूरी तरह ठीक है और चिंता करने की कोई बात नहीं है? बिल्कुल सही नहीं है इसका क्या अर्थ है।

उत्तर

18

एक सूक्ष्म अंतर यह है कि आपका दायरा अलग है, और इससे त्रुटियां हो सकती हैं। पहले मामले में स्थिरांक AppCore में देखा जाएगा, जबकि दूसरे मामले में स्थिरांक AppCore::Tenant में देखा जाएगा। यदि आप निरंतर नामों को पूरी तरह अर्हता प्राप्त करते हैं तो इससे कोई फर्क नहीं पड़ता है।

Foo = :problem 

module A 
    Foo = 42 

    # looks up A::Foo because of lexical scope 
    module B 
    def self.foo 
     Foo 
    end 
    end 
end 

# looks up ::Foo because of lexical scope 
module A::C 
    def self.foo 
    Foo 
    end 
end 

# Looks up A::Foo, fully qualified ... ok technically ::A::Foo is fully qualified, but meh. 
module A::D 
    def self.foo 
    A::Foo 
    end 
end 

A::B.foo # => 42 
A::C.foo # => :problem 
A::D.foo # => 42 

आप से भीतर MembersController तो यह आप के लिए एक फर्क कर सकते हैं AppCore::Tenant में परिभाषित स्थिरांक की बात कर रहे हैं। सूक्ष्म लेकिन संभवतः महत्वपूर्ण, और इसके बारे में जागरूक होना अच्छा है। मैंने इसे वास्तविक जीवन में मारा है जब मेरे पास Util मॉड्यूल था जिसमें String सबमिशन था। मैंने Util में एक विधि को स्थानांतरित कर दिया और यह तोड़ दिया क्योंकि उस विधि के अंदर String अब Util::String पर संदर्भित है। मैंने उसके बाद कुछ नामकरण सम्मेलनों को बदल दिया।

आपके Tenant मॉड्यूल में हमेशा नेस्टेड क्लास के रूप में MembersController होगा। आपके कोडबेस में कहीं और आप AppCore::Tenant::MembersController देख सकते हैं। यदि आप बेहतर अलगाव चाहते हैं तो आपको अपने मॉडल वर्गों को अलग-अलग नाम देना चाहिए, या उन्हें AppCore::Model या इसी तरह के मॉड्यूल के अंदर रखना चाहिए। यदि आप रेल का उपयोग कर रहे हैं तो आपको कुछ सम्मेलनों को कम करना होगा, लेकिन इसके लिए आवश्यक कॉन्फ़िगरेशन बहुत खराब नहीं है।

+0

मुझे मॉडल मॉडल में यह मॉडल डालने का विचार पसंद है (यह एक मुट्ठी भर है)। अच्छा सुझाव। – typeoneerror

+1

ओटीओएच कॉम्पैक्ट फॉर्म पैरेंट मॉड्यूल/क्लास नहीं बनाता है, जबकि नेस्टेड फॉर्म करता है, जिससे हार्ड-टू-डिस्क त्रुटियां भी हो सकती हैं। – radiospiel

0

मुझे पता है कि आप तकनीकी विनिर्देशों के बारे में पूछ रहे हैं, और सामी ने इसका उत्तर दिया है। लेकिन मैं अपने आप को मदद नहीं कर सकते और पूछने के लिए:

वहाँ पहली जगह तुम क्यों करना चाहते हैं में एक विशेष कारण है ...

  1. ... पदानुक्रम की तरह एक "पथ" परिचय?
  2. ... नियंत्रक को मॉडल श्रेणी के अंदर रखें?

यदि मुझे 1 की आवश्यकता महसूस होगी, तो शायद मेरे पास असली पथों को प्रतिबिंबित करने वाला सरल "कंटेनर" मॉड्यूल होगा।यही है, app/model/tenant.rb =>Model::Tenant और app/controller/members_controller.rb =>Controller::MembersController

लेकिन स्पष्ट रूप से, मुझे वास्तव में इसके पीछे तर्क नहीं दिख रहा है। XyzController सम्मेलन द्वारा नियंत्रकों को पहले से ही आसानी से देखा जा रहा है। मॉडल (ज्यादातर बार, मुझे लगता है) बल्कि आसानी से उनके डोमेन की तरह प्रकृति द्वारा मान्यता प्राप्त हैं। चूंकि रूबी को क्लास नामों के लिए पथ नामों से मिलान करने की आवश्यकता नहीं होती है (उदाहरण के लिए जावा के विपरीत), स्पष्ट 1-स्तर नामकरण सम्मेलन मेरे लिए अधिक उपयोगी होगा।

उप-मॉड्यूल/उप-वर्ग पदानुक्रम रत्नों के लिए बहुत उपयोगी, या आवश्यक है, जहां वे संघर्ष से बचने के लिए नामस्थानों की तरह काम करते हैं।

2) (मॉडल के अंदर नियंत्रक) मूल रूप से गलत है। नियंत्रक मॉडल से बहुत अलग हैं और निश्चित रूप से एक के अंदर नहीं रहते हैं।

0

यदि आप नेस्टेड का उपयोग कर रहे हैं और शीर्ष-स्तर के नम्पस्पेस पर वापस जाना चाहते हैं तो आप :: का उपयोग कर सकते हैं।

def class user < ActiveRecord::Base 
    NAME = "Real User" 
end 

module SomeModule 
    def class User 
     Name = "Fake User" 
    end 
    module InnerModule 
     class MyClass 
      puts User.NAME # "Fake User" 
      puts ::User.Name # "Real User" 
     end 
    end 
end