रेलें: update_attribute बनाम update_attributes


255
Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

ये दोनों AR को अपडेट करने के लिए स्पष्ट रूप से बताए बिना एक ऑब्जेक्ट को अपडेट करेंगे।

रेल एपीआई कहते हैं:

update_attribute के लिए

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

update_attributes के लिए

पास-इन हैश से सभी विशेषताओं को अपडेट करता है और रिकॉर्ड को बचाता है। यदि ऑब्जेक्ट अमान्य है, तो बचत विफल हो जाएगी और झूठी लौटा दी जाएगी।

इसलिए अगर मैं ऑब्जेक्ट को मान्य नहीं करना चाहता, तो मुझे update_attribute का उपयोग करना चाहिए। क्या होगा अगर मेरे पास पहले से यह अपडेट है_ तो क्या यह स्टैकओवरफ्लो होगा?

मेरा सवाल यह है कि update_attribute भी सेव या सिर्फ वैरिफिकेशन से पहले बाईपास कर देता है।

इसके अलावा, update_attributes को हैश पास करने के लिए सही सिंटैक्स क्या है ... शीर्ष पर मेरा उदाहरण देखें।


आप कॉलबैक के update_attributeअंदर एक स्टेटमेंट क्यों डालना चाहते हैं before_save? मैं इसके लिए एक अच्छा कारण नहीं सोच सकता।
डैनियल पीटरज़

1
मेरे पास ऐसी वस्तुएं हैं जिन्हें अद्यतन की गई वस्तु की मात्रा के आधार पर अद्यतन करने की आवश्यकता है। बेहतर तरीका क्या है?
तत्कालीन

क्या मैं सही हूं, कि आपको जिन वस्तुओं को अद्यतन करने की आवश्यकता है, वे उस वस्तु का गुण हैं जिसे आप सहेज रहे हैं? यदि हाँ, तो आप बस उन्हें सेट कर सकते हैं, और उन्हें उस वस्तु के साथ अद्यतन किया जाएगा जो वैसे भी सहेजा जाता है (क्योंकि वे before_saveकॉलबैक के भीतर सेट हैं )। update_attribute(:discount, 0.1) if amount > 100तुम्हारे बजाय Fe कर सकता था discount = 0.1 if amount > 100। ऑब्जेक्ट पर update_attributeकॉल save, जो इस मामले में अनावश्यक है, क्योंकि स्टेटमेंट एक before_saveकॉलबैक के अंदर है और वैसे भी बच जाएगा। मुझे उम्मीद है कि इसका कोई अर्थ है।
डैनियल पीटरज़ेक

हां और ना। हालाँकि, ऑब्जेक्ट्स की स्थिति जिसे आप संदर्भित कर रहे हैं, अन्य शर्तों पर आकस्मिक है जिन्हें सहेजने से पहले संसाधित नहीं किया जा सकता है।
तत्पश्चात

3
एक नोट के रूप में, ये विधियाँ सत्यापन को छोड़ देती हैं, लेकिन फिर भी कॉलबैक करेंगी, जैसे कि after_save ...
rogerdpack

जवाबों:


328

कृपया देखें update_attribute। शो सोर्स पर क्लिक करने पर आपको निम्नलिखित कोड मिलेगा

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2614
2614:       def update_attribute(name, value)
2615:         send(name.to_s + '=', value)
2616:         save(false)
2617:       end

और अब देखें update_attributesऔर अपने कोड को देखें

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2621
2621:       def update_attributes(attributes)
2622:         self.attributes = attributes
2623:         save
2624:       end

दोनों के बीच अंतर है update_attributeका उपयोग करता है save(false), जबकि update_attributesका उपयोग करता है saveया आप कह सकते हैं save(true)

लंबे विवरण के लिए क्षमा करें, लेकिन मैं जो कहना चाहता हूं वह महत्वपूर्ण है। save(perform_validation = true), अगर perform_validationयह गलत है तो बाईपास हो जाएगा (स्किप उचित शब्द होगा) से जुड़े सभी सत्यापनsave

दूसरे प्रश्न के लिए

इसके अलावा, update_attributes को हैश पास करने के लिए सही सिंटैक्स क्या है ... शीर्ष पर मेरा उदाहरण देखें।

आपका उदाहरण सही है।

Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

या

Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"

या यदि आपके पास हैश में सभी फ़ील्ड डेटा और नाम हैं, तो params[:user]यहां बताएं कि बस उपयोग करें

Object.update_attributes(params[:user])

7
कम से कम कॉलबैक के बारे में आपका कथन गलत है Rails 3। यह स्रोत में टिप्पणियों में बहुत स्पष्ट रूप से कहता है कि "कॉलबैक आह्वान किया गया है"।
बाटकिंस

मैं @Batkins दूसरे क्या कहते हैं
आरएएफ

3
@ बाटकिंस अभी भी सत्यापन नहीं चलाए जा रहे हैं - यह सबसे महत्वपूर्ण हिस्सा है :)
बाघिन

1
ऊपर दिए गए लिंक अब कम से कम रेल के रूप में सटीक नहीं हैं 5.1 । इन विधियों को ActiveRecord :: Persistence पर ले जाया गया। आप अद्यतन जानकारी यहाँ पा सकते हैं: अद्यतन विशेषता और यहाँ update_attributes नोट: update_attributesअब इसके लिए एक उपनाम हैupdate
tgf

74

टिप: कमिट a7f4b0a1 केupdate_attribute माध्यम से रेल 4 में पदावनत किया जा रहा है । इसके पक्ष में हटा देता है ।update_attributeupdate_column


45
यह अब सच नहीं है; विधि फिर से जोड़ दी गई है। देखें github.com/rails/rails/pull/6738#issuecomment-39584005
डेनिस

20
update_attributeसत्यापन मान्य है, लेकिन कॉलबैक का सम्मान करता है, update_columnसत्यापन और कॉलबैक और :updated_atupdate
वॉन्ट

2
क्या वे पहले से ही अपना मन बना लेंगे। reset_column, update_column को भी हटा दिया गया।
अहानिबेकाड

2
update_columnपदावनत नहीं किया जाता है, लेकिन update_columns(name: value)इष्ट है। reset_columnनिकाल दिया गया है।
वनब्री

15

update_attribute

यह विधि मॉडल आधारित सत्यापन को लागू किए बिना ऑब्जेक्ट की एकल विशेषता को अद्यतन करती है।

obj = Model.find_by_id(params[:id])
obj.update_attribute :language, java

update_attributes

यह विधि एकल ऑब्जेक्ट की कई विशेषताओं को अपडेट करती है और मॉडल आधारित सत्यापन भी पास करती है।

attributes = {:name => BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)

आशा है कि यह उत्तर स्पष्ट होगा कि सक्रिय रिकॉर्ड की किस विधि का उपयोग करना है।


12

यह भी ध्यान देने योग्य है कि update_attributeअपडेट की जाने वाली वांछित विशेषता को सफेद रंग के साथ सूचीबद्ध करने की आवश्यकता नहीं है, attr_accessibleइसे अपडेट करने के लिए बड़े पैमाने पर असाइनमेंट विधि का विरोध करना update_attributesहोगा जो केवल attr_accessibleनिर्दिष्ट विशेषताओं को अपडेट करेगा ।


8

update_attributeबस एक मॉडल के केवल एक विशेषता को अद्यतन करता है, लेकिन हम update_attributesविधि में कई विशेषताओं को पारित कर सकते हैं ।

उदाहरण:

user = User.last

#update_attribute
user.update_attribute(:status, "active")

यह मान्यता को पारित करता है

#update_attributes
user.update_attributes(first_name: 'update name', status: "active")

सत्यापन विफल होने पर यह अपडेट नहीं होता है।


बहुत अच्छी तरह से समझाया गया। धन्यवाद!
डिएगो सोमर

6

शानदार जवाब। ध्यान दें कि रूबी 1.9 और इसके बाद के संस्करण के लिए आप (और मुझे लगता है कि) update_attributes के लिए नए हैश सिंटैक्स का उपयोग करना चाहिए:

Model.update_attributes(column1: "data", column2: "data")

6

आप एक विशेषता या अद्यतन रिकॉर्ड (नियम 4 को अद्यतन) update_attribute, update, update_column, update_columns etc. http://www.davidverhasselt.com/set-attributes-in-activerecord/ को असाइन करने के सभी संभावित तरीकों से संबंधित इस ब्लॉग पोस्ट पर जाने में रुचि रख सकते हैं । उदाहरण के लिए यह मान्यताओं को चलाने, ऑब्जेक्ट के अद्यतन_त को छूने या कॉलबैक को ट्रिगर करने जैसे पहलुओं में भिन्न है।

ओपी के सवाल के जवाब के रूप में update_attributeपास कॉलबैक से नहीं होता है।


हाँ यकीन है, मैंने जवाब को संशोधित किया। प्रतिक्रिया के लिए धन्यवाद।
adamliesko

4

update_attributeऔर update_attributesसमान हैं, लेकिन एक बड़े अंतर के साथ: सत्यापन update_attribute नहीं चलता है।

इसके अलावा:

  • update_attributeएकल विशेषता के साथ रिकॉर्ड अपडेट करने के लिए उपयोग किया जाता है ।

    Model.update_attribute(:column_name, column_value1)
  • update_attributesकई विशेषताओं के साथ रिकॉर्ड अपडेट करने के लिए उपयोग किया जाता है ।

    Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)

ये दो तरीके वास्तव में उनके समान नामों और कार्यों को भ्रमित करने के लिए आसान हैं। इसलिए के update_attributeपक्ष में हटाया जा रहा है update_column

अब, Rails4 में आप Model.update_column(:column_name, column_value)के स्थान पर उपयोग कर सकते हैंModel.update_attribute(:column_name, column_value)

के बारे में अधिक जानकारी प्राप्त करने के लिए यहां क्लिक करेंupdate_column


4

आपके प्रश्न का उत्तर देने के लिए, update_attributeस्काई प्री "सेविंग्स" को सेव करता है , लेकिन फिर भी यह किसी भी अन्य कॉलबैक after_saveआदि को चलाता है , इसलिए यदि आप वास्तव में "केवल कॉलम अपडेट करना चाहते हैं और किसी भी एआर क्रॉफ्ट को छोड़ना चाहते हैं" तो आपको (जाहिरा तौर पर) का उपयोग करना होगा

Model.update_all(...)देख https://stackoverflow.com/a/7243777/32453


2

हाल ही में मैं update_attributeबनाम update_attributesऔर सत्यापन के मामले में भाग गया , इसलिए समान नाम, इतना अलग व्यवहार, इतना भ्रामक।

हैश पास करने update_attributeऔर सत्यापन को बायपास करने के लिए आप कर सकते हैं:

object = Object.new
object.attributes = {
  field1: 'value',
  field2: 'value2',
  field3: 'value3'
}
object.save!(validate: false)

1

मुझे लगता है कि अगर आपका सवाल है कि पहले से_में एक अद्यतन_अभियोजन हो रहा है और अंतहीन लूप के लिए आगे बढ़ेगा (अद्यतित_अभियोजन कॉल से पहले_सैव कॉलबैक में, मूल रूप से एक अद्यतन_अभियोग कॉल द्वारा ट्रिगर)

मुझे पूरा यकीन है कि यह पहले से कॉलबैक को बायपास कर देता है क्योंकि यह वास्तव में रिकॉर्ड को बचाता नहीं है। आप उपयोग करके सत्यापन को ट्रिगर किए बिना एक रिकॉर्ड भी बचा सकते हैं

माडल। Sss झूठी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.