2012-09-22 27 views
5

मैं एक रूबी वस्तु (एक ActiveRecord वस्तु, विशेष रूप से) User नामित किया है। यह find_by_id, find_by_auth_token इत्यादि जैसी विधियों का जवाब देता है। हालांकि, ये विधियां नहीं हैं जिन्हें def या define_method के माध्यम से परिभाषित किया गया है। इसके बजाए, वे गतिशील विधियां हैं जिन्हें method_missing के माध्यम से संभाला जाता है।वस्तु # विधि और गतिशील प्रतिसाददाताओं

मैं उदाहरण के Object#method के माध्यम से इन तरीकों में से एक के लिए एक संदर्भ प्राप्त करने के लिए, .:

User.method(:find_by_auth_token) 

यह इस तरह नहीं दिखता है करना चाहते हैं, हालांकि काम करता है। सबसे अच्छा समाधान मैं आया हूं:

proc { |token| User.find_by_auth_token(token) } 

क्या इस तरह के एक रैपर विधि का उपयोग करने के आसपास कोई अन्य तरीका है? क्या मैं वास्तव में गतिशील तरीकों के लिए Object#method का उपयोग करने में असमर्थ हूं?

+2

किसी को जो भविष्य में इस पर ठोकर के लिए, इन गतिशील खोजक तरीकों रेल में हटा दिया जाएगा 4.0। मैं व्यक्तिगत रूप से उन पर शीर्ष कार्यक्षमता जोड़ने की सतर्क रहूंगा। https://github.com/rails/activerecord-deprecated_finders –

उत्तर

5

सरल जवाब "नहीं" -इस एक ही रास्ता सामान्य में गारंटी नहीं है कि Object#method(:foo)Method का एक उदाहरण वापस आ जाएगी है एक विधि foo वस्तु पर नामित को परिभाषित कर रहा है।

अधिक समेकित उत्तर यह है कि आप को Method का उदाहरण Object#respond_to_missing? s.tr ओवरराइड करके एक उदाहरण लौटने में सक्षम कर सकते हैं। :foo दिए जाने पर यह true देता है। उदाहरण के लिए:

class User 
    def respond_to_missing?(method_name, include_private = false) 
    method_name.to_s.start_with?('find_by_') 
    end 
end 

m = User.new.method(:find_by_hackish_means) 
# => #<Method: User#find_by_hackish_means> 

(यह सुनिश्चित करना है कि विधि वास्तव में परिभाषित किया गया है आप पर निर्भर है):

m.call 
# => NoMethodError: undefined method `find_by_hackish_means' for #<User:0x123> 
+2

यहाँ इस विषय पर एक अधिक गहराई से ब्लॉग पोस्ट है: http://robots.thoughtbot.com/post/28335346416/always-define-respond-to-missing- जब – pje

+1

+1 ओवरराइडिंग। तो यह वास्तव में रेल की गलती है यह काम नहीं करता है। मैंने इसे उस संबंध में ठीक करना शुरू कर दिया है, उदा। https://github.com/rails/rails/pull/6169 –

+0

ठीक है, यह समझ में आता है। और @ मार्क-एंड्रेलाफोर्ट्यून, आपने मेरे प्रश्न का उत्तर दिया कि मुझे तुरंत इस जवाब के जवाब में था। :) आप दोनों के लिए धन्यवाद! –

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