बिना अपडेट किए अपडेट करें


386

क्या update_attributes का कोई विकल्प है जो रिकॉर्ड को सहेजता नहीं है?

इसलिए मैं कुछ ऐसा कर सकता था:

@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save

BTW, मुझे पता है कि मैं कर सकता हूं @car.model = 'Sierra', लेकिन मैं उन सभी को एक लाइन पर अपडेट करना चाहता हूं।


आपका क्या मतलब है "रिकॉर्ड नहीं बचा"?
अनातोली

update_attributes मॉडल DB को बचाता है। मैं सोच रहा हूँ अगर वहाँ एक समान विधि है कि नहीं है।
tybro0103

3
गैर-विनाशकारी विधि का गुण । देखें एपीआई जानकारी के लिए
अनातोली

3
आप कॉल को बचाने के बिना, किसी भी विशेषता के एक अद्यतन को update_column (नाम, मूल्य) का उपयोग कर सकते हैं। 1. मान्यता छोड़ दी जाती है। 2. कॉलबैक छोड़ दिया जाता है। 3. अद्यतन_ट / अद्यतन_ऑन कालम अद्यतन नहीं है यदि वह स्तंभ उपलब्ध है। apidock.com/rails/ActiveRecord/Persistence/update_column
एंटोनी

10
3.1+ के लिए, assign_attributes apidock.com/rails/ActiveRecord/Base/assign_attributes
elado

जवाबों:


596

मुझे विश्वास है कि आप जो खोज रहे हैं वह है assign_attributes

यह मूल रूप से update_attributes के समान है, लेकिन यह रिकॉर्ड को नहीं बचाता है:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :is_admin, :as => :admin
end

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name        # => "Bob"
user.is_admin?   # => false
user.new_record? # => true

आपका उदाहरण थोड़ा भ्रामक है क्योंकि आपने मॉडल से इस पंक्ति को चिपकाया नहीं है attr_accessible :is_admin, :as => :admin;)
रोबिन

@ रॉबिन या बस attr_protected :is_admin:। या: attr_accessible :nameइस उदाहरण में वह बिंदु है: is_admin संरक्षित है। मुझे यह भी ध्यान देना चाहिए कि बड़े पैमाने पर एक संरक्षित विशेषता को असाइन करने का प्रयास .assign_attributesवास्तव में एक उठाता है ActiveModel::MassAssignmentSecurity::Error, भले ही वह उदाहरण में नहीं दिखाया गया हो।
Ajedi32

हाँ, लेकिन मेरी लाइन आपके द्वारा लिंक किए गए डॉक्टर से है। मैं सिर्फ इतना कह रहा हूं कि आपको पूरा उदाहरण कॉपी / पेस्ट करना चाहिए। लेकिन हां, आप बस इतना कह सकते हैं कि यह संरक्षित है।
रॉबिन

@ रोबिन मैं उदाहरण को थोड़ा और विशिष्ट होने के लिए अपडेट करूंगा। डॉक्स में उदाहरण भी थोड़ा भ्रामक है, क्योंकि यह उल्लेख नहीं करता है कि user.assign_attributes({ :name => 'Josh', :is_admin => true })एक त्रुटि संदेश उठाता है और वास्तव में उपयोगकर्ता के नाम की संपत्ति निर्धारित नहीं करता है।
अजादि32

7
assign_attributes रेल 3.1 से उपलब्ध है, इसलिए यदि आप अभी भी रेल का पुराना संस्करण चला रहे हैं तो आप इसका उपयोग नहीं कर सकते।
Haegin

173

आप उपयोग कर सकते हैं assign_attributesया attributes=(वे समान हैं)

अपडेट के तरीके धोखा शीट (रेल 6 के लिए):

  • update= assign_attributes+save
  • attributes= = का उपनाम assign_attributes
  • update_attributes = पदावनत, का उपनाम update

स्रोत:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment .rb

एक और धोखा पत्र:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet


1
साफ और छोटा। धन्यवाद।
फ्रीमैनॉइड

1
.attributes = val के मामले में, यदि आपका मॉडल has_one है और किसी अन्य मॉडल को स्वीकार नहीं करता है, तो उस_model_attributes (आईडी के बिना) को पारित करने से मौजूदा has_one मॉडल को हटा दिया जाएगा, भले ही वह स्थायी नहीं रहा हो (जैसे सेव)। लेकिन इस तरह से व्यवहार करने के लिए असाइन नहीं किया गया है।
ClassyPimp

65

आप 'विशेषताएँ' विधि का उपयोग कर सकते हैं:

@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}

स्रोत: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

विशेषताएँ = (new_attributes, guard_protected_attributes = true) आपको विशेषता नाम (जो फिर से स्तंभ नामों से मेल खाता है) से मेल खाते कीज़ के साथ हैश में पास करके एक बार में सभी विशेषताओं को सेट करने देता है।

यदि guard_protected_attributes सत्य (डिफ़ॉल्ट) है, तो संवेदनशील विशेषताओं को attr_protected मैक्रो का उपयोग करके बड़े पैमाने पर असाइनमेंट के इस रूप से संरक्षित किया जा सकता है। या आप वैकल्पिक रूप से निर्दिष्ट कर सकते हैं कि कौन से गुण attr_accessible मैक्रो के साथ एक्सेस किए जा सकते हैं। तब इसमें शामिल सभी विशेषताओं को बड़े पैमाने पर नियत नहीं किया जाएगा।

class User < ActiveRecord::Base
  attr_protected :is_admin
end

user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username   # => "Phusion"
user.is_admin?  # => false

user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin?  # => true

7

बचत, उपयोग या तो बिना एक ActiveRecord मॉडल के लिए मूल्यों की बड़े पैमाने पर काम के लिए assign_attributesया attributes=तरीकों। ये तरीके रेल 3 और नए में उपलब्ध हैं। हालांकि, इसके बारे में जागरूक होने के लिए मामूली अंतर और संस्करण-संबंधी गोच हैं।

दोनों विधियाँ इस उपयोग का अनुसरण करती हैं:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }

@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }

ध्यान दें कि न तो विधि सत्यापन करेगा या कॉलबैक निष्पादित नहीं करेगा; कॉलबैक और सत्यापन तब होगा जब saveकॉल किया जाएगा।

रेल 3

attributes=assign_attributesरेल 3 से थोड़ा अलग है । attributes=यह जाँच करेगा कि जो तर्क पास किया गया वह एक हैश है, और यदि यह नहीं है तो तुरंत वापस आ जाता है; assign_attributesऐसा कोई हैश चेक नहीं है। के लिए ActiveRecord विशेषता असाइनमेंट API दस्तावेज़attributes= देखें ।

निम्नलिखित अमान्य कोड केवल विशेषताओं को सेट किए बिना चुपचाप विफल हो जाएंगे:

@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]

attributes= चुपचाप व्यवहार करेंगे जैसे कि असाइनमेंट सफलतापूर्वक किए गए थे, जब वास्तव में, वे नहीं थे।

यह अमान्य कोड एक अपवाद बढ़ाएगा जब assign_attributesएन्कोडिंग सरणी के हैश कीज़ को सख्त करने की कोशिश की जाएगी :

@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])

assign_attributesके लिए एक NoMethodErrorअपवाद उठाएगा stringify_keys, यह दर्शाता है कि पहला तर्क कोई हैश नहीं है। अपवाद स्वयं वास्तविक कारण के बारे में बहुत जानकारीपूर्ण नहीं है, लेकिन यह तथ्य कि अपवाद होता है, बहुत महत्वपूर्ण है।

इन मामलों के बीच एकमात्र अंतर सामूहिक असाइनमेंट के लिए उपयोग की जाने वाली विधि है: attributes=चुपचाप सफल होता है, और assign_attributesयह सूचित करने के लिए अपवाद उत्पन्न करता है कि त्रुटि हुई है।

ये उदाहरण विवादित लग सकते हैं, और वे एक हद तक हैं, लेकिन एपीआई से डेटा परिवर्तित करते समय, या केवल डेटा परिवर्तन की एक श्रृंखला का उपयोग करने और Hash[]फाइनल के परिणामों को भूल जाने पर इस प्रकार की त्रुटि आसानी से हो सकती है .map। अपने विशेषता असाइनमेंट से हटाए गए कुछ कोड 50 से ऊपर कोड और 3 फ़ंक्शन बनाए रखें, और आपको विफलता के लिए एक नुस्खा मिला है।

रेल 3 के साथ सबक यह है: हमेशाassign_attributes इसके बजाय उपयोग करें attributes=

रेलें ४

रेल 4 में, attributes=बस एक उपनाम है assign_attributes। के लिए ActiveRecord विशेषता असाइनमेंट API दस्तावेज़attributes= देखें ।

रेल 4 के साथ, या तो विधि का उपयोग परस्पर विनिमय किया जा सकता है। पहले तर्क के रूप में हैश को पारित करने में विफलता के परिणामस्वरूप बहुत ही उपयोगी अपवाद होगा:ArgumentError: When assigning attributes, you must pass a hash as an argument.

सत्यापन

यदि आप तैयारी में पूर्व उड़ान असाइनमेंट कर रहे हैं save, तो आप को बचाने से पहले, साथ ही मान्य करने में रुचि हो सकती है। इसके लिए आप valid?और invalid?तरीकों का इस्तेमाल कर सकते हैं । दोनों बूलियन मान लौटाते हैं। valid?यह सच है कि यदि सहेजा गया मॉडल सभी मान्यताओं या झूठ को पारित करता है, अगर वह ऐसा नहीं करता है। invalid?बस का उलटा हैvalid?

valid? इस तरह इस्तेमाल किया जा सकता है:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?

यह आपको कॉल करने से पहले किसी भी सत्यापन के मुद्दों को संभालने की क्षमता देगा save

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