2009-07-27 14 views
36

त्वरित उदाहरण: कोई उपयोगकर्ता किसी उपयोगकर्ता नाम को फ़ॉर्म में दर्ज करता है, और मुझे ऐप के डेटाबेस में इसे संग्रहीत करने से पहले उस टेक्स्ट उपयोगकर्ता नाम को बनाना होगा, जिससे इसे स्थायी रूप से कम किया जा सके।रेल पर रूबी - क्या मैं सहेजने से पहले डेटा संशोधित कर सकता हूं?

मैं यह कोड कहां रखूंगा, और मैं डेटा को कम करने के लिए कैसे उपयोग करूं?

धन्यवाद।

उत्तर

46

आप अपने उपयोगकर्ता मॉडल, जैसे कि तरह कुछ में ActiveRecords कॉलबैक में से एक इस्तेमाल कर सकते हैं:

before_save { |user| user.username = user.username.downcase } 
+1

ActiveRecord कॉलबैक पर अधिक: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html – Zargony

+1

यदि आपके पास ऐसे हुक हैं और/या गुणों पर किए गए कई संचालन हैं तो आप उनके लिए विधियां भी बना सकते हैं और दे सकते हैं भेड़ के बच्चे के बजाय विधि नाम। आप [विशेषता-फ़िल्टर] (http://rubydoc.info/gems/attribute-filters/1.2.2/) मणि भी देख सकते हैं जो उस प्रक्रिया को सरल बनाता है यदि आपके पास कई कॉलबैक हैं जो विशेषताओं को बदलने के लिए डिज़ाइन किए गए हैं। – siefca

0

सामान्य स्थिति में, प्रपत्र पर सबमिट बटन एक नियंत्रक कार्रवाई प्रतिनिधि चाहिए जहां पैरामीटर [: उपयोगकर्ता नाम उपलब्ध है। कुछ मॉडेल.अपडेट (पैरा) या बनाने (पैराम्स) बनाने से पहले आप इसे कम कर सकते हैं।

तो आप इसे नियंत्रक कार्रवाई में कर सकते हैं।

class User < ActiveRecord::Base 
    def username=(val) 
    write_attribute(:username, val.downcase) 
    end 
end 
+0

आपको कंट्रोलर और मॉडल को कसकर युग्मित करने के परिणामों के बारे में सोचना होगा। क्या होता है जब दो नियंत्रकों को इस मॉडल का उदाहरण बनाने की आवश्यकता होती है? उपयोगकर्ता बनाने के लिए कंसोल का उपयोग करने के बारे में क्या, और डेवलपर भूल जाता है कि उपयोगकर्ता नाम को कम करना चाहिए? यूनिट परीक्षण के बारे में क्या? मुझे लगता है कि effkay द्वारा सुझाए गए ActiveRecord कॉलबैक का उपयोग करना बेहतर तरीका है। –

+0

हां मैंने उसे भी ऊपर उठाया। मेरा तर्क: जब तक यह एक स्थान पर मुझे वास्तव में परवाह नहीं है। ऐसा लगता है कि ओपी के सवाल से कई जगहें नहीं थीं .. इसलिए मैं सबसे सरल चीज के लिए गया जो संभवतः काम कर सकता था। इसके अलावा आपके पास हमेशा मॉडल नहीं हो सकता है .. इस परिदृश्य में हालांकि ऐसा लगता है कि ओपी को एक का उपयोग करना चाहिए। – Gishu

70

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

संपादित करें: कृपया ध्यान दें कि उस मॉडल से जुड़े पहले_सव के भीतर Model.save नहीं कर सकता है, अन्यथा आप एक अनंत लूप में समाप्त हो जाते हैं। आपको एक अपडेट_ट्रिब्यूट या कुछ करने की आवश्यकता होगी।

+4

हां, यह बेहतर समाधान है। किसी ऑब्जेक्ट को डेटाबेस में सहेजने से पहले यह स्थिरता सुनिश्चित करेगा। – molf

+0

धन्यवाद ने मुझे एक समस्या को ठीक करने में बहुत मदद की जो मुझे थका रहा था! :) – Vicer

+1

यह उत्तर स्वीकार किया जाना चाहिए, इसे शीर्ष पर ले जाएं! – RonLugge

0

मैं एक Observer मॉडल के लिए और before_save विधि में इस कार्रवाई कर जोड़ने का सुझाव होगा:

11

अपने उपयोगकर्ता मॉडल में (मॉडल/user.rb), ActiveRecord कॉलबैक का लाभ लें:

before_save do 
    self.username = self.username.downcase 
end 
+0

यह मामला मेरे मामले में काम करता है – Neeraj

4

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

मैं अपना जवाब यहां योगदान दे रहा हूं क्योंकि यह धागा इस कार्य को पूरा करने के लिए पहला Google परिणाम था, लेकिन पूरे लौटने में false समस्या शामिल नहीं थी।

यदि आपकी कोई भी कॉलबैक false वापस लौटा दी जाएगी तो सब कुछ डीबी में वापस घुमाया जाएगा।

मैं डेटाबेस में @offer.accepted = false में स्वीकार नहीं किए जाने के लिए एक ऑफ़र सेट करने का प्रयास कर रहा था। समस्या यह थी कि इस लाइन ने पूरी प्रक्रिया को झूठी वापसी और पूरी प्रक्रिया को रोलबैक करने का कारण बताया।

मैं एक अंतर्निहित वापसी true बाद में

कोड है कि काम में घालना द्वारा यह तय:

before_save {|offer| offer.accepted = false; true}

Takeaway: अपने कॉलबैक false वापस नहीं लौट सकते हैं यदि आप उन्हें सफल होना चाहते हैं।

स्रोत: rails 3 : Do i need to give return true in a before_save callback for an object.save to work?

1
def username=(str) 
super(str.downcase) 
end 

मुझे लगा कि यह बहुत आसान है।

संबंधित मुद्दे

 संबंधित मुद्दे