2011-09-27 6 views
66

मेरे पास एक विशेष रूप से जटिल मॉडल है जिसमें सत्यापन और कॉलबैक परिभाषित किए गए हैं। व्यापार की जरूरत अब एक विशेष परिदृश्य की मांग करती है जहां एक नए रिकॉर्ड को जोड़ने के लिए सत्यापन और कॉलबैक छोड़ना आवश्यक है। ऐसा करने का सबसे अच्छा तरीका क्या है?रेल 3 स्किप सत्यापन और कॉलबैक

उत्तर

116

इस रेल 3 में काम करता है:

Model.skip_callback(:create) 
model.save(:validate => false) 
Model.set_callback(:create) 

(API docs और related question)

+5

आप फिर से उपयोग करने के लिए' '' set_callback आवश्यकता नहीं है? मैं इस धारणा के तहत था कि 'skip_callback''' इसे फिर से सक्षम होने तक अक्षम करता है। –

+1

मुझे लगता है कि हाँ, मैं इस विधि का कभी भी उपयोग नहीं करता, अधिक जानकारी http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback – Dinatih

+19

यह थ्रेड सुरक्षित नहीं हो सकता है? यह एक उदाहरण स्तर पर सेट करने में सक्षम होना अच्छा होगा .. –

1

अपने मॉडल सकता है जो आपको कॉलबैक को छोड़ करने के लिए एक विधि जोड़ने के बारे में क्या?

class Foo < ActiveRecord::Base 
    after_save :do_stuff 

    def super_secret_create(attrs) 
    self.skip_callback(:create) 
    self.update_attributes(attrs) 
    self.save(:validate => false) 
    self.set_callback(:create) 
    end 
end 

आप कुछ इस तरह का उपयोग कर खत्म करते हैं, तो मैं मॉडल नाम के बजाय विधि में स्वयं का उपयोग कर नाम का connascence से बचने के लिए सिफारिश करेंगे।

मैं भी स्वेन फुच्स से एक सार है कि अच्छा लग रहा है भर में भाग गया, यह here

+1

मुझे यह दृष्टिकोण पसंद है लेकिन 'skip_callback' क्लास विधि के रूप में दिख रहा है जबकि' update_attributes' है एक उदाहरण विधि, क्या आप इरादा चाहते हैं? हम्म मुझे यह नहीं मिला, एपीआई दस्तावेज़ कहता है कि 'skip_callback' उदाहरण विधि है लेकिन यह रेल कंसोल में नहीं है, विषम। –

2

मेरे ले इस (नोट ऐसा हुआ करता था: इस अक्षम कर देता है पर कॉलबैक अद्यतन के लिए, बनाने के लिए, हटा सकते हैं और दूसरों को आप उन्हें सरणी के लिए जोड़ने की जरूरत)।

begin 
     [:create, :save].each{|a| self.class.skip_callback(a) } # We disable callbacks on save and create 

     # create new record here without callbacks, tou can also disable validations with 
     # .save(:validate => false) 
    ensure 
     [:create, :save].each{|a| self.class.set_callback(a) } # and we ensure that callbacks are restored 
    end 
+0

उपरोक्त, लेकिन फिर यह मेरे 3.2.6 ऐप के लिए काम नहीं किया। मैं Model.skip_callback को कॉल कर रहा था (: बनाएं,: बाद) – TuteC

+0

यह 3.0+ के लिए समाधान है 2.x पर काम नहीं करेगा - लेकिन मुझे याद है जब मैं इस समाधान के लिए देख रहा था, तो मैंने समाधान के लिए ठोकर खाई है .x जो 3.x –

29

उपयोग ActiveRecord::Persistence#update_column, इस तरह:

Model.update_column(field, value) 
+0

के लिए काम नहीं करता है, आपके द्वारा लिंक किए गए दस्तावेज़ों के अनुसार: "कॉलबैक लागू किए जाते हैं।" – eggie5

+5

मुझे लगता है कि आपने 'update_attribute' के लिए प्रलेखन को देखा, न कि' update_column' के लिए। यदि आप 'update_column' के लिए प्रलेखन देखते हैं, तो यह एक कॉलम के लिए 'update_columns' के बराबर है। 'Update_columns' के लिए दस्तावेज़ स्पष्ट रूप से बताते हैं कि सत्यापन और कॉलबैक छोड़ दिए गए हैं। – bowsersenior

+0

मेरा जीवन बचाओ! मैंने skip_callback और अन्य तरीकों की कोशिश की, कोई भाग्य नहीं। यह काम! –

0

इस हैक पिछले पर मेरे लिए काम किया (नए सिरे से परिभाषित वस्तु के लिए _notify_comment_observer_for_after_create विधि):

if no_after_create_callback 
    def object._notify_comment_observer_for_after_create; nil; end 
end 
1

मैं लंघन के लिए एक सरल मणि ने लिखा है सत्यापन adhoc, लेकिन यह शायद छोड़ने कॉल बैक भी शामिल करने के लिए अद्यतन किया जा सकता है।

https://github.com/npearson72/validation_skipper

आप मणि में can_skip_validation_for लेने के लिए और भी कॉलबैक लंघन के लिए कार्यक्षमता जोड़ सकते हैं। शायद विधि can_skip_validation_and_callbacks_for

सब कुछ वही काम करेगा। अगर आप ऐसा करने में मदद चाहते हैं, तो मुझे बताएं।

1

मैं skip_callback दृष्टिकोण का उपयोग न करने की अनुशंसा करता हूं क्योंकि यह थ्रेड सुरक्षित नहीं है। sneaky save gem हालांकि यह अभी से सीधे एसक्यूएल चलाता है। ध्यान दें कि यह मान्यताओं को ट्रिगर नहीं करेगा, इसलिए आपको उन्हें स्वयं कॉल करना होगा (उदा: my_model.valid?)।

यहाँ उनके डॉक्स से कुछ नमूने हैं: लक्ष्य को लगाएं या कॉलबैक या सत्यापन के बिना एक रिकॉर्ड अद्यतन करने के लिए है

# Update. Returns true on success, false otherwise. 
existing_record.sneaky_save 

# Insert. Returns true on success, false otherwise. 
Model.new.sneaky_save 

# Raise exception on failure. 
record.sneaky_save! 
7

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

class ImportedUser < ActiveRecord::Base 
    # To import users with no validations or callbacks 
    self.table_name = 'users' 
end 

यह रेल के हर संस्करण के साथ काम करता है, threadsafe है, और पूरी तरह से अपने मौजूदा कोड के लिए कोई संशोधनों के साथ सभी का सत्यापन और कॉलबैक दूर करता है।इनमें से

ImportedUser.new(person_attributes) 
+1

यह इतना स्मार्ट है। मुझे सिरदर्द बचाया! –

0

कोई नहीं करता है, तो अपने सत्यापन डेटाबेस में ही लिखा जाता है काम करेंगे: बस की तरह, ऑब्जेक्ट सम्मिलित करने के लिए अपने नए वर्ग का उपयोग करना न भूलें। (: बनाने) `` `

+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+ 
| Field        | Type            | Null | Key | Default   | Extra   | 
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+ 
| status        | enum('Big','Small','Ugly','Stupid','Apologetic') | NO |  | Stupid    |    | 
संबंधित मुद्दे