ruby on rails - रेल पर रूबी: वैश्विक स्थिरांक कहां परिभाषित करें?




ruby-on-rails constants (8)

मैं बस रेल वेबपैप पर अपनी पहली रूबी के साथ शुरू कर रहा हूं। मुझे विभिन्न मॉडल, विचार, नियंत्रक, और इसी तरह का एक गुच्छा मिला है।

मैं वास्तव में वैश्विक स्थिरांक की परिभाषाओं को छूने के लिए एक अच्छी जगह खोजना चाहता हूं, जो मेरे पूरे ऐप पर लागू होता है। विशेष रूप से, वे मेरे मॉडल के तर्क, और मेरे विचारों में किए गए निर्णयों में दोनों लागू होते हैं। मुझे इन परिभाषाओं को रखने के लिए कोई भी DRY स्थान नहीं मिल रहा है, जहां वे मेरे सभी मॉडलों और मेरे सभी विचारों में भी उपलब्ध हैं।

एक विशिष्ट उदाहरण लेने के लिए, मुझे एक निरंतर COLOURS = ['white', 'blue', 'black', 'red', 'green'] । यह मॉडल और विचारों दोनों में, पूरे स्थान पर उपयोग किया जाता है। मैं इसे केवल एक ही स्थान पर कहां परिभाषित कर सकता हूं ताकि यह पहुंच योग्य हो?

मैंने क्या कोशिश की है:

  • Model.rb फ़ाइल में लगातार कक्षा चर जो वे सबसे अधिक जुड़े हुए हैं, जैसे कि @@COLOURS = [...] । लेकिन मुझे इसे परिभाषित करने के लिए एक सौहार्दपूर्ण तरीका नहीं मिल सका ताकि मैं अपने विचारों में Card.COLOURS लिख Card.first.COLOURSCard.first.COLOURS तरह कुछ Card.COLOURS बजाय Card.first.COLOURS
  • मॉडल पर एक विधि, def colours ['white',...] end तरह कुछ def colours ['white',...] end - एक ही समस्या।
  • Application_helper.rb में एक विधि - यह वही है जो मैं अब तक कर रहा हूं, लेकिन मददगार केवल विचारों में पहुंच योग्य हैं, मॉडल में नहीं
  • मुझे लगता है कि मैंने application.rb या environment.rb में कुछ कोशिश की हो सकती है, लेकिन वे वास्तव में सही नहीं लगते हैं (और वे या तो काम नहीं करते हैं)

मॉडल और विचारों से दोनों सुलभ होने के लिए कुछ भी परिभाषित करने का कोई तरीका नहीं है? मेरा मतलब है, मुझे मॉडल पता है और विचार अलग होना चाहिए, लेकिन निश्चित रूप से कुछ डोमेनों में उन्हें एक ही डोमेन-विशिष्ट ज्ञान को संदर्भित करने की आवश्यकता होगी?


आपकी हालत के अनुसार, आप कुछ पर्यावरणीय चर भी परिभाषित कर सकते हैं, और इसे रूबी कोड में ENV['some-var'] माध्यम से ENV['some-var'] सकते हैं, यह समाधान आपके लिए उपयुक्त नहीं हो सकता है, लेकिन मुझे उम्मीद है कि यह दूसरों की मदद कर सकता है।

उदाहरण: आप विभिन्न फाइलें बना सकते हैं .development_env , .production_env , .test_env और इसे अपने एप्लिकेशन वातावरण के अनुसार लोड करें, इस dotenv-rails जांच करें जो आपके लिए इसे स्वचालित करता है।


एक और विकल्प, यदि आप अपने स्थिरांक को एक ही स्थान पर परिभाषित करना चाहते हैं:

module DSL
  module Constants
    MY_CONSTANT = 1
  end
end

लेकिन फिर भी उन्हें पूरी तरह से योग्य तरीके से पहुंचने के बिना उन्हें विश्व स्तर पर दृश्यमान बनाते हैं:

DSL::Constants::MY_CONSTANT # => 1
MY_CONSTANT # => NameError: uninitialized constant MY_CONSTANT
Object.instance_eval { include DSL::Constants }
MY_CONSTANT # => 1

कक्षा विधि का प्रयोग करें:

def self.colours
  ['white', 'red', 'black']
end

फिर Model.colours उस सरणी को वापस कर देगा। वैकल्पिक रूप से, नामस्थान संघर्ष से बचने के लिए एक प्रारंभकर्ता बनाएं और स्थिरांक को मॉड्यूल में लपेटें।


कुछ विकल्प:

निरंतर उपयोग करना:

class Card
  COLOURS = ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
end

क्लास इंस्टेंस वैरिएबल का उपयोग करके आलसी लोड किया गया:

class Card
  def self.colours
    @colours ||= ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
  end
end

यदि यह वास्तव में वैश्विक स्थिरता है ( हालांकि इस प्रकृति के वैश्विक स्थिरांक से बचें ), तो आप उदाहरण के लिए config/initializers/my_constants.rb में शीर्ष-स्तरीय स्थिरता डालने पर भी विचार कर सकते हैं।


यदि आपका मॉडल स्थिरांक के लिए वास्तव में "जिम्मेदार" है तो आपको वहां रहना चाहिए। आप एक नया ऑब्जेक्ट उदाहरण बनाये बिना उन्हें एक्सेस करने के लिए क्लास विधियां बना सकते हैं:

class Card < ActiveRecord::Base
  def self.colours
    ['white', 'blue']
  end
end

# accessible like this
Card.colours

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

class Card < ActiveRecord::Base
  @@colours = ['white', 'blue']
  cattr_reader :colours
end

# accessible the same as above

उपर्युक्त दो विकल्प आपको आवश्यक होने पर एक्सेसर विधि के प्रत्येक आमंत्रण पर लौटाए गए सरणी को बदलने की अनुमति देते हैं। यदि आपके पास वास्तव में अपरिवर्तनीय निरंतर सत्य है, तो आप इसे मॉडल वर्ग पर भी परिभाषित कर सकते हैं:

class Card < ActiveRecord::Base
  COLOURS = ['white', 'blue'].freeze
end

# accessible as
Card::COLOURS

आप वैश्विक स्थिरांक भी बना सकते हैं जो प्रारंभिक में हर जगह से उपलब्ध हैं जैसे कि निम्नलिखित उदाहरण में। यह शायद सबसे अच्छा स्थान है, यदि आपके रंग वास्तव में वैश्विक हैं और एक से अधिक मॉडल संदर्भ में उपयोग किए जाते हैं।

# put this into config/initializers/my_constants.rb
COLOURS = ['white', 'blue'].freeze

नोट: जब हम ऊपर स्थिरांक परिभाषित करते हैं, अक्सर हम सरणी को freeze करना चाहते हैं। इससे दूसरे कोड को बाद में (अनजाने में) सरणी को संशोधित करने से रोकता है जैसे कि एक नया तत्व जोड़ना। एक बार ऑब्जेक्ट जमे हुए हो जाने पर, इसे और नहीं बदला जा सकता है।


यदि एक से अधिक कक्षाओं में निरंतर आवश्यकता है, तो मैंने इसे सभी कैप्स में हमेशा कॉन्फ़िगर / प्रारंभकर्ता / contant.rb में रखा है (नीचे दिए गए राज्यों की सूची काटा गया है)।

STATES = ['AK', 'AL', ... 'WI', 'WV', 'WY']

वे मॉडल कोड को छोड़कर आवेदन के माध्यम से उपलब्ध हैं जैसे कि:

    <%= form.label :states, %>
    <%= form.select :states, STATES, {} %>

एक मॉडल में निरंतर उपयोग करने के लिए, निरंतर उपलब्ध कराने के लिए attr_accessor का उपयोग करें।

class Customer < ActiveRecord::Base
    attr_accessor :STATES

    validates :state, inclusion: {in: STATES, message: "-- choose a State from the drop down list."}
end

वैश्विक चर config/initializers निर्देशिका में घोषित किया जाना चाहिए

COLOURS = %w(white blue black red green)

आवेदन-व्यापी वैश्विक स्थिरांक रखने के लिए एक आम जगह config/application अंदर है।

module MyApp
  FOO ||= ENV.fetch('FOO', nil)
  BAR ||= %w(one two three)

  class Application < Rails::Application
    config.foo_bar = :baz
  end
end




global