दिलचस्प पोस्ट
String.split () का प्रयोग करते हुए शब्दों के जोड़े को निकालना पारंपरिक एएसपी। नेट वेब फॉर्म बनाम एमवीसी GIT_WORK_TREE क्या है, मुझे इस ENV var को सेट करने की आवश्यकता क्यों नहीं है, अब क्यों? कमेंट टेम्प्लेट पर संकेतक क्षय प्राथमिकता क्यों लेते हैं? हेडर प्रति स्रोत फ़ाइल सी # अपनी कक्षा का नाम प्राप्त करना कोणीय जेएस के साथ बूटस्ट्रैप नेविबर सक्रिय वर्ग कैसे सेट करें? PL / pgSQL में '$$' के लिए क्या उपयोग किया जाता है AngularJS एक नियंत्रक लोड गतिशील जावा के लिए मूल कीवर्ड क्या है? जावा सॉकेट / सीरियललाइज़ेशन, ऑब्जेक्ट अपडेट नहीं होगा अजगर में जन्म तिथि से आयु साझा किए गए पन्नों में एन्क्रिप्ट डेटा एंड्रॉइड 4.3 ब्लूटूथ कम ऊर्जा अस्थिर WinDbg में एसओएस लोड करने में असमर्थ

मैं ActiveRecord में डिफ़ॉल्ट मान कैसे सेट करूं?

मैं ActiveRecord में डिफ़ॉल्ट मान कैसे सेट कर सकता हूं?

मुझे प्रतीक से एक पोस्ट दिखाई देती है जो कोड के बदसूरत, जटिल हिस्से का वर्णन करती है: http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model

class Item < ActiveRecord::Base def initialize_with_defaults(attrs = nil, &block) initialize_without_defaults(attrs) do setter = lambda { |key, value| self.send("#{key.to_s}=", value) unless !attrs.nil? && attrs.keys.map(&:to_s).include?(key.to_s) } setter.call('scheduler_type', 'hotseat') yield self if block_given? end end alias_method_chain :initialize, :defaults end 

मैंने निम्नलिखित उदाहरणों को चारों ओर googling देखा है:

  def initialize super self.status = ACTIVE unless self.status end 

तथा

  def after_initialize return unless new_record? self.status = ACTIVE end 

मैंने यह भी देखा है कि लोग इसे अपने प्रवास में डालते हैं, लेकिन मैं इसे मॉडल कोड में परिभाषित देखना चाहता हूं।

क्या ActiveRecord मॉडल में फ़ील्ड के लिए डिफ़ॉल्ट मान सेट करने के लिए एक विहित तरीका है?

Solutions Collecting From Web of "मैं ActiveRecord में डिफ़ॉल्ट मान कैसे सेट करूं?"

उपलब्ध तरीकों में से प्रत्येक के साथ कई मुद्दे हैं, लेकिन मेरा मानना ​​है कि निम्नलिखित कारणों के लिए जाने के बाद एक कॉलबैक शुरू करने का तरीका है:

  1. default_scope नए मॉडलों के लिए मूल्यों को इनिशियलाइज़ करेगा, लेकिन फिर यह वह गुंजाइश बन जाएगा, जिस पर आपको मॉडल मिल जाएगा। यदि आप बस कुछ संख्याओं को 0 में प्रारंभ करना चाहते हैं तो यह वही नहीं है जो आप चाहते हैं।
  2. आपके माइग्रेशन में डिफॉल्ट को परिभाषित भी समय के हिस्से का काम करता है … जैसा कि पहले से ही उल्लेख किया गया है जब आप केवल मॉडल को कॉल करते हैं तो यह काम नहीं करेगा।
  3. initialize ओवरराइड initialize काम कर सकता है, लेकिन super कॉल करने के लिए मत भूलना!
  4. फ्यूजन की तरह एक प्लगइन का उपयोग करना थोड़ा हास्यास्पद हो रहा है यह रूबी है, क्या हमें वास्तव में कुछ डिफ़ॉल्ट मानों को प्रारंभ करने के लिए एक प्लगइन की ज़रूरत है?
  5. after_initialize को रेल 3 के रूप में नापसंद किया गया है । जब मैं रेल after_initialize में after_initialize करने के बाद ओवरराइड करता after_initialize मुझे कंसोल में निम्न चेतावनी मिलती है:

प्रत्यावर्तन चेतावनी: बेस # after_initialize को नापसंद किया गया है, कृपया बेस का उपयोग करें। बाद में प्रारंभ करें: इसके बजाय विधि (/ उपयोगकर्ता / मी / मैप / ऐप / मॉडल / माय_मॉडल से फोन किया गया: 15)

इसलिए मैं कहूंगा कि एक after_initialize कॉलबैक लिखें, जो आपको इसके समान एसोसिएशनों पर डिफ़ॉल्ट सेट करने के अलावा डिफ़ॉल्ट विशेषताओं की सुविधा देता है:

  class Person < ActiveRecord::Base has_one :address after_initialize :init def init self.number ||= 0.0 #will set the default value only if it's nil self.address ||= build_address #let's you set a default association end end 

अब आपके पास अपने मॉडलों के आरंभीकरण के लिए सिर्फ एक जगह है। मैं इस पद्धति का उपयोग कर रहा हूँ जब तक कि कोई बेहतर से बेहतर न हो।

चेतावनियां:

  1. बूलियन फ़ील्ड के लिए करें:

    self.bool_field = true if self.bool_field.nil?

    अधिक जानकारी के लिए इस उत्तर पर पॉल रसेल की टिप्पणी देखें

  2. यदि आप केवल एक मॉडल के लिए कॉलम का एक सबसेट चुन रहे हैं (यानी; Person.select(:firstname, :lastname).all पसंद में select का उपयोग करके Person.select(:firstname, :lastname).all ) आपको एक MissingAttributeError यदि आपकी MissingAttributeError पद्धति किसी कॉलम तक MissingAttributeError select खंड में शामिल किया गया आप इस मामले से इस तरह से रक्षा कर सकते हैं:

    self.number ||= 0.0 if self.has_attribute? :number

    और एक बूलियन कॉलम के लिए …

    self.bool_field = true if (self.has_attribute? :bool_value) && self.bool_field.nil?

    यह भी ध्यान रखें कि सिंटैक्स रेल 3.2 से अलग है। (नीचे क्लिफ डार्लिंग की टिप्पणी देखें)

हम माइग्रेशन के माध्यम से डेटाबेस में डिफ़ॉल्ट मान डालते हैं (प्रत्येक कॉलम परिभाषा पर :default विकल्प निर्दिष्ट करके) और सक्रिय रिकॉर्ड इन मानों का उपयोग प्रत्येक विशेषता के लिए डिफ़ॉल्ट सेट करने के लिए करते हैं।

आईएमएचओ, यह दृष्टिकोण एआर के सिद्धांतों के साथ गठबंधन किया गया है: कॉन्फ़िगरेशन के ऊपर सम्प्रेषण, सूखा, तालिका परिभाषा मॉडल को चलाता है, अन्य तरह से नहीं।

ध्यान दें कि डिफ़ॉल्ट अभी भी अनुप्रयोग (रूबी) कोड में हैं, हालांकि मॉडल में नहीं बल्कि माइग्रेशन (ओं) में

कुछ साधारण मामलों को डेटाबेस स्कीमा में एक डिफ़ॉल्ट परिभाषित करके संभाला जा सकता है, लेकिन वह गणना किए गए मूल्यों और अन्य मॉडलों की कुंजी सहित कई जटिल मामलों को नियंत्रित नहीं करता है। इन मामलों के लिए मैं ऐसा करता हूं:

 after_initialize :defaults def defaults unless persisted? self.extras||={} self.other_stuff||="This stuff" self.assoc = [OtherModel.find_by_name('special')] end end 

मैंने after_initialize का उपयोग करने का निर्णय लिया है, लेकिन मैं नहीं चाहता कि यह उन वस्तुओं पर लागू किया जाए जो केवल उन नए या निर्मित किए गए हैं मुझे लगता है कि यह लगभग चौंकाने वाला है कि इस स्पष्ट उपयोग के मामले में एक after_new कॉलबैक प्रदान नहीं किया गया है, लेकिन मैंने यह पुष्टि करके यह किया है कि वस्तु पहले से ही जारी है, यह इंगित करता है कि यह नया नहीं है।

ब्रैड मरे का जवाब देखने के बाद यह भी क्लीनर है अगर स्थिति को कॉलबैक अनुरोध पर ले जाया गया है:

 after_initialize :defaults, unless: :persisted? # ":if => :new_record?" is equivalent in this context def defaults self.extras||={} self.other_stuff||="This stuff" self.assoc = [OtherModel.find_by_name('special')] end 

इस फ्यूजन लोगों के लिए कुछ अच्छा प्लगइन है

बाद में केवल निम्नलिखित कार्य करके कॉलबैक पैटर्न को प्रारंभ करने के लिए सुधारा जा सकता है

 after_initialize :some_method_goes_here, :if => :new_record? 

यदि आपकी इनिट कोड को एसोसिएशन से निपटने की आवश्यकता है, तो इसका एक गैर-तुच्छ लाभ है, क्योंकि निम्न कोड एक सूक्ष्म n + 1 को चालू करता है यदि आप प्रारंभिक रिकॉर्ड को संबद्ध किए बिना

 class Account has_one :config after_initialize :init_config def init_config self.config ||= build_config end end 

रेल 5 + में, आप अपने मॉडल के भीतर विशेषता विधि का उपयोग कर सकते हैं, उदाहरण के लिए:

 class Account < ApplicationRecord attribute :locale, :string, default: 'en' end 

मैं attribute-defaults मणि का उपयोग करता हूं

प्रलेखन से: sudo gem install attribute-defaults और अपने ऐप को require 'attribute_defaults' जोड़ें।

 class Foo < ActiveRecord::Base attr_default :age, 18 attr_default :last_seen do Time.now end end Foo.new() # => age: 18, last_seen => "2014-10-17 09:44:27" Foo.new(:age => 25) # => age: 25, last_seen => "2014-10-17 09:44:28" 

यह वही है जो कन्स्ट्रक्टर हैं! मॉडल की initialize विधि को ओवरराइड करें

after_initialize विधि का उपयोग करें

दोस्तों को सुपुर्द करें, मैं निम्नलिखित काम कर रहा हूं:

 def after_initialize self.extras||={} self.other_stuff||="This stuff" end 

एक जादू की तरह काम करता है!

प्रस्तावित उत्तरों की तुलना में एक भी बेहतर / क्लीनर संभावित तरीका एक्सेसर को ओवरराइट करना है, इस प्रकार से:

 def status self['status'] || ACTIVE end 

ActiveRecord :: बेस दस्तावेज़ में और " स्टैक ओवरफ्लो " से अधिक स्वयं का उपयोग करने पर "ओवरराइटिंग डिफॉल्ट एक्सेसर्स" देखें।

पहली बातें पहले: मैं जेफ के उत्तर से असहमत नहीं हूं। यह समझ में आता है जब आपका ऐप छोटा होता है और आपका तर्क सरल होता है मैं यहाँ एक अंतर्दृष्टि देने का प्रयास कर रहा हूं कि एक बड़ा आवेदन बनाने और बनाए रखने में समस्या कैसे हो सकती है। मैं इस दृष्टिकोण का उपयोग करने की सिफारिश नहीं करता है, जब कुछ छोटे बनाना, लेकिन एक वैकल्पिक दृष्टिकोण के रूप में इसे ध्यान में रखना:


यहां एक सवाल यह है कि रिकॉर्ड पर यह डिफ़ॉल्ट व्यापार तर्क है। अगर ऐसा है, तो मैं इसे ओआरएम मॉडल में रखने के लिए सावधान रहना होगा। चूंकि फ़ील्ड रैव का उल्लेख सक्रिय है , यह व्यापार तर्क की तरह ध्वनि करता है। उदाहरण उपयोगकर्ता सक्रिय है।

मैं ओआरएम मॉडल में कारोबार की चिंता क्यों करूँगा?

  1. यह एसआरपी टूटता है ActiveRecord :: बेस से कोई भी वर्ग उत्तराधिकारी पहले से बहुत कुछ कर रहा है, उनमें से प्रमुख डेटा संगति (मान्यता) और दृढ़ता (सहेजने) है व्यापारिक तर्क डालकर, हालांकि, एआर :: बेस ब्रेक एसआरपी के साथ में यह छोटा है।

  2. यह परीक्षण करने के लिए धीमी है अगर मैं अपने ओआरएम मॉडल में होने वाले तर्क के किसी भी रूप का परीक्षण करना चाहता हूं, तो मेरे परीक्षणों को चलाने के लिए रेल को आरम्भ करना होगा। यह आपके आवेदन की शुरुआत में बहुत अधिक समस्या नहीं है, लेकिन जब तक आपके यूनिट परीक्षणों को चलाने के लिए लंबा समय न ले लेता है, तब तक जमा हो जाएगा।

  3. यह लाइन से भी अधिक एसआरपी तोड़ देगा, और ठोस तरीके से। कहें कि हमारे व्यवसाय के लिए अब हमें उपयोगकर्ताओं को ईमेल करना होगा जब आइटम सक्रिय हो जाएंगे? अब हम आइटम ORM मॉडल में ईमेल तर्क जोड़ रहे हैं, जिनकी प्राथमिक जिम्मेदारी किसी आइटम को मॉडलिंग कर रही है। यह ईमेल तर्क के बारे में परवाह नहीं करना चाहिए यह व्यापार साइड इफेक्ट का मामला है। ये ओआरएम मॉडल में शामिल नहीं हैं।

  4. विविधता लाने में मुश्किल है I मैंने परिपक्व रेल एप्लिकेशन को इनट_प्रकार: स्ट्रिंग फ़ील्ड के आधार पर डेटाबेस के जैसी चीज़ों के साथ देखा है, जिसका एकमात्र उद्देश्य प्रारंभिक तर्क को नियंत्रित करना है। यह संरचनात्मक समस्या को ठीक करने के लिए डेटाबेस को प्रदूषित करता है। बेहतर तरीके हैं, मुझे विश्वास है।

पोरो रास्ता: हालांकि यह थोड़ी अधिक कोड है, लेकिन यह आपको अपने ORM मॉडल और व्यवसाय तर्क को अलग रखने की अनुमति देता है। यहां कोड को सरल किया गया है, लेकिन इस विचार को दिखाना चाहिए:

 class SellableItemFactory def self.new(attributes = {}) record = Item.new(attributes) record.active = true if record.active.nil? record end end 

फिर इसके स्थान पर, एक नया आइटम बनाने का तरीका होगा

 SellableItemFactory.new 

और मेरा परीक्षण अब बस यह सत्यापित कर सकता है कि मद फाइनैंट सेट आइटम पर सक्रिय है, अगर इसके पास मूल्य नहीं है कोई रेल प्रारंभिक आवश्यकता नहीं, कोई एसआरपी ब्रेकिंग नहीं। जब मद प्रारंभिक अधिक उन्नत हो जाता है (जैसे एक स्थिति फ़ील्ड सेट करता है, एक डिफ़ॉल्ट प्रकार, आदि) ItemFactory यह जोड़ा हो सकता है। अगर हम दो प्रकार के चूक के साथ समाप्त होते हैं, तो हम ऐसा करने के लिए एक नया BusinesCaseItemFactory बना सकते हैं।

नोट: कारखाने को कई सक्रिय चीजों का निर्माण करने की अनुमति देने के लिए यहाँ निर्भरता इंजेक्शन का उपयोग करने के लिए भी फायदेमंद हो सकता है, लेकिन मैं इसे सादगी के लिए छोड़ दिया। यहां यह है: self.new (klass = आइटम, गुण = {})

समान प्रश्न, लेकिन सभी के पास थोड़ा अलग संदर्भ है: – मैं रेल सक्रियरेकॉर्ड के मॉडल में विशेषताओं के लिए एक डिफ़ॉल्ट मान कैसे बना सकता हूं?

सर्वश्रेष्ठ उत्तर: आप क्या चाहते हैं पर निर्भर करता है!

यदि आप प्रत्येक ऑब्जेक्ट को किसी मूल्य से शुरू करना चाहते हैं : after_initialize :init उपयोग करें

क्या आप पृष्ठ को खोलने पर new.html फ़ॉर्म को डिफ़ॉल्ट मान प्राप्त करना चाहते हैं? https://stackoverflow.com/a/5127684/1536309 का उपयोग करें

 class Person < ActiveRecord::Base has_one :address after_initialize :init def init self.number ||= 0.0 #will set the default value only if it's nil self.address ||= build_address #let's you set a default association end ... end 

यदि आप चाहते हैं कि प्रत्येक ऑब्जेक्ट को उपयोगकर्ता इनपुट से गणना की जाने वाली मान है: before_save :default_values उपयोग before_save :default_values आप चाहते हैं कि उपयोगकर्ता X और फिर Y = X+'foo' ? उपयोग:

 class Task < ActiveRecord::Base before_save :default_values def default_values self.status ||= 'P' end end 

After_initialize समाधान के साथ समस्या यह है कि आपको डीबी के हर एक ऑब्जेक्ट के बाद after_initialize जोड़ना होगा, भले ही आप इस विशेषता का उपयोग करें या नहीं। मैं एक आलसी-लोड दृष्टिकोण का सुझाव देता हूं

विशेषता विधियों (गेटर्स) निश्चित रूप से स्वयं के तरीके हैं, इसलिए आप उन्हें ओवरराइड कर सकते हैं और एक डिफ़ॉल्ट प्रदान कर सकते हैं। कुछ इस तरह:

 Class Foo < ActiveRecord::Base # has a DB column/field atttribute called 'status' def status (val = read_attribute(:status)).nil? ? 'ACTIVE' : val end end 

जब तक कि किसी ने बताया न हो, आपको फ़ू। फ़ंड_ बाय_स्टेटस ('सक्रिय') करना होगा। उस स्थिति में मुझे लगता है कि डीबी को इसका समर्थन करने के लिए आप वास्तव में अपने डेटाबेस बाधाओं में डिफ़ॉल्ट सेट करना चाहते हैं।

 class Item < ActiveRecord::Base def status self[:status] or ACTIVE end before_save{ self.status ||= ACTIVE } end 

यह एक लंबे समय के लिए उत्तर दिया गया है, लेकिन मुझे अक्सर डिफ़ॉल्ट मान की आवश्यकता है और उन्हें डेटाबेस में नहीं रखना पसंद करते हैं। मैं एक DefaultValues चिंता पैदा:

 module DefaultValues extend ActiveSupport::Concern class_methods do def defaults(attr, to: nil, on: :initialize) method_name = "set_default_#{attr}" send "after_#{on}", method_name.to_sym define_method(method_name) do if send(attr) send(attr) else value = to.is_a?(Proc) ? to.call : to send("#{attr}=", value) end end private method_name end end end 

और फिर इसे अपने मॉडलों में इसी तरह प्रयोग करें:

 class Widget < ApplicationRecord include DefaultValues defaults :category, to: 'uncategorized' defaults :token, to: -> { SecureRandom.uuid } end 

मैंने यह भी देखा है कि लोग इसे अपने प्रवास में डालते हैं, लेकिन मैं इसे मॉडल कोड में परिभाषित देखना चाहता हूं।

क्या ActiveRecord मॉडल में फ़ील्ड के लिए डिफ़ॉल्ट मान सेट करने के लिए एक विहित तरीका है?

रेल 5 के पहले कैनोनिकल रेल मार्ग वास्तव में माइग्रेशन में सेट करने के लिए था, और जब भी db/schema.rb को देखने के लिए चाहते हैं कि किसी भी मॉडल के लिए डीबी द्वारा कौन से डिफ़ॉल्ट मान सेट किए जा रहे हैं।

जेफ पेरिन के उत्तर के उत्तर के विपरीत (जो थोड़ी पुरानी है), कुछ रेल जादू के चलते, Model.new का प्रयोग करते समय माइग्रेशन दृष्टिकोण भी डिफ़ॉल्ट पर लागू होगा। रेल 4.1.16 में सत्यापित कार्य।

सरलतम चीज अक्सर सबसे अच्छी होती है कोडबेस में कम ज्ञान ऋण और भ्रम के संभावित अंक। और यह 'सिर्फ काम करता है'

 class AddStatusToItem < ActiveRecord::Migration def change add_column :items, :scheduler_type, :string, { null: false, default: "hotseat" } end end 

null: false डीबी में नल मूल्यों को अस्वीकार कर देता है, और, एक अतिरिक्त लाभ के रूप में, यह सभी पूर्व-मौजूदा डीबी रिकॉर्ड भी इस फ़ील्ड के लिए डिफ़ॉल्ट मान के साथ सेट किया गया है। यदि आप चाहें तो माइग्रेशन में आप इस पैरामीटर को बाहर कर सकते हैं, लेकिन मुझे यह बहुत आसान मिला!

रेल 5 + में कैनोनिकल तरीका है, क्योंकि @ लुकास कैटन ने कहा:

 class Item < ActiveRecord::Base attribute :scheduler_type, :string, default: 'hotseat' end 

हालांकि ऐसा करते हुए डिफ़ॉल्ट मान सेट करने के लिए अधिकतर मामलों में भ्रमित और अजीब है, तो आप इसका उपयोग कर सकते हैं :default_scope भी स्क्विल की टिप्पणी यहां देखें ।

after_initialize विधि को नापसंद किया जाता है, बजाय कॉलबैक का उपयोग करें।

 after_initialize :defaults def defaults self.extras||={} self.other_stuff||="This stuff" end 

हालांकि, का उपयोग करते हुए : आपके माइग्रेशन में डिफ़ॉल्ट अभी भी सबसे स्वच्छ तरीका है।

मुझे पता चला है कि सत्यापन विधि का उपयोग करने से चूक सेट करने पर बहुत अधिक नियंत्रण प्रदान करता है अपडेट के लिए आप डिफ़ॉल्ट (या असफलता) को भी सेट कर सकते हैं यदि आप वास्तव में चाहते थे तो आप बनाम अपडेट के लिए एक अलग डिफ़ॉल्ट मान भी सेट कर सकते हैं ध्यान दें कि डिफ़ॉल्ट को #valid तक सेट नहीं किया जाएगा? कहा जाता है।

 class MyModel validate :init_defaults private def init_defaults if new_record? self.some_int ||= 1 elsif some_int.nil? errors.add(:some_int, "can't be blank on update") end end end 

एक after_initialize विधि को परिभाषित करने के बारे में, प्रदर्शन समस्याएं हो सकती हैं क्योंकि after_initialize को प्रत्येक वस्तु द्वारा वापस लाया जाता है: ढूंढें: http://guides.rubyonrails.org/active_record_validations_callbacks.html#after_initialize-and-after_find

मैं ActiveModel::MissingAttributeError त्रुटि देने के बाद after_initialize साथ समस्याओं में भाग गया जटिल हो रहा है जब:

उदाहरण के लिए:

 @bottles = Bottle.includes(:supplier, :substance).where(search).order("suppliers.name ASC").paginate(:page => page_no) 

"खोज" में। .where स्थितियों की हैश है

इसलिए मैंने इस तरह प्रारंभिक रूप से अधिरोहित करके इसे खत्म कर दिया:

 def initialize super default_values end private def default_values self.date_received ||= Date.current end 

यह सुनिश्चित करने के लिए super कॉल आवश्यक है कि ऑब्जेक्ट को ActiveRecord::Base से अपना कस्टमाइज़ कोड करने से पहले सही तरीके से आरंभ करना, अर्थात: default_values

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

  aasm column: "status" do state :available, initial: true state :used # transitions end 

यह अभी भी सहेजे न गए रिकॉर्ड के लिए मूल्य को प्रारंभ नहीं करता है, लेकिन यह अपने आप को init या जो कुछ भी साथ रोलिंग की तुलना में थोड़ा क्लीनर है, और आप अपने सभी स्थितियों के लिए scopes जैसे एसा के अन्य लाभ काटते हैं।

https://github.com/keithrowell/rails_default_value

 class Task < ActiveRecord::Base default :status => 'active' end 

मैं "default_value_for" मणि का उपयोग करने का सुझाव देता हूं: https://github.com/FooBarWidget/default_value_for

कुछ मुश्किल परिदृश्य हैं जो प्रारंभिक पद्धति को ओवरराइड करने के लिए बहुत ज्यादा आवश्यक हैं, जो कि मणि करता है

उदाहरण:

आपका डीबी डिफ़ॉल्ट नल है, आपका मॉडल / रूबी-डिफ़ाइंड डिफ़ॉल्ट "कुछ स्ट्रिंग" है, लेकिन आप वास्तव में किसी भी कारण के लिए मूल्य निर्धारित करना चाहते हैं : MyModel.new(my_attr: nil)

यहां अधिकांश समाधान मूल्य को शून्य पर सेट करने में विफल होंगे, और इसके बजाय इसे डिफ़ॉल्ट पर सेट कर दिया जाएगा

ठीक है, इसलिए * ||= दृष्टिकोण लेने के बजाय, आप my_attr_changed? स्विच करते हैं my_attr_changed?

लेकिन अब अपने डीबी डिफ़ॉल्ट "कुछ स्ट्रिंग" की कल्पना करें, आपका मॉडल / रूबी-डिफ़ाइंड डिफ़ॉल्ट "कुछ अन्य स्ट्रिंग" है, लेकिन एक निश्चित परिदृश्य के तहत, आप "कुछ स्ट्रिंग" (डीबी डिफ़ॉल्ट) को मान सेट करना चाहते हैं : MyModel.new(my_attr: 'some_string')

इसका परिणाम my_attr_changed? झूठी होने के कारण यह मान डीबी डिफ़ॉल्ट से मेल खाता है, जो बदले में आपके रूबी-डिफ़ाइंड डिफाल्ट कोड को आग लगा देगा और "कुछ अन्य स्ट्रिंग" पर सेट करेगा – फिर, जो वांछित नहीं है


उन कारणों के लिए मुझे नहीं लगता है कि यह ठीक से एक after_initialize हुक के साथ पूरा किया जा सकता है

दोबारा, मुझे लगता है कि "default_value_for" मणि सही दृष्टिकोण ले रहा है: https://github.com/FooBarWidget/default_value_for

रेल 3 में default_scope का उपयोग करें

एपीआई डॉक्टर

ActiveRecord डेटाबेस (स्कीमा) में परिभाषित डिफ़ॉल्ट के बीच अंतर और अनुप्रयोग (मॉडल) में किए गए डिफ़ॉल्ट को अस्पष्ट करता है। आरंभ के दौरान, यह डेटाबेस स्कीमा को पार्स करता है और वहां निर्दिष्ट किसी भी डिफ़ॉल्ट मान को नोट करता है बाद में, ऑब्जेक्ट बनाते समय, यह डेटाबेस को छूने के बिना उन स्कीमा-निर्दिष्ट डिफ़ॉल्ट मान को असाइन करता है।

विचार-विमर्श

एपी डॉक्स से http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html अपने मॉडल में before_validation विधि का उपयोग करें, यह आपको कॉल बनाने और अपडेट करने के लिए विशिष्ट प्रारंभिक बनाने का विकल्प देता है उदा। इस उदाहरण में (फिर से कोड एपीआई डॉक्स उदाहरण से लिया गया) नंबर फ़ील्ड एक क्रेडिट कार्ड के लिए आरंभ किया गया है। आप जो चाहें सेट करने के लिए आसानी से इसका अनुकूलन कर सकते हैं

 class CreditCard < ActiveRecord::Base # Strip everything but digits, so the user can specify "555 234 34" or # "5552-3434" or both will mean "55523434" before_validation(:on => :create) do self.number = number.gsub(%r[^0-9]/, "") if attribute_present?("number") end end class Subscription < ActiveRecord::Base before_create :record_signup private def record_signup self.signed_up_on = Date.today end end class Firm < ActiveRecord::Base # Destroys the associated clients and people when the firm is destroyed before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } before_destroy { |record| Client.destroy_all "client_of = #{record.id}" } end 

आश्चर्य है कि उनका सुझाव यहां नहीं दिया गया है