2012-09-22 17 views
5

User adlı bir Ruby nesnesine (özellikle ActiveRecord nesnesine) sahibim. find_by_id, find_by_auth_token, vb. Gibi yöntemlere yanıt verir. Ancak, bunlar def veya define_method aracılığıyla tanımlanmış yöntemler değildir. Bunun yerine, method_missing aracılığıyla işlenen dinamik yöntemlerdir.Nesne # yöntemi ve dinamik yanıt verenler

Ben

User.method(:find_by_auth_token) 

Bu gibi görünmüyor .:, Object#method aracılığıyla örneğin bu yöntemlerden birine başvuru almak istiyorum

olsa çalışır. Ben ile gelip en iyi çözümdür: bu gibi bir sarıcı yöntemi kullanarak etrafında başka bir şekilde

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

var mı? Dinamik yöntemler için Object#method'u gerçekten kullanamıyorum mu?

+2

, bu dinamik bulucu yöntemleri Rails kaldırılacaktır 4.0. Kişisel olarak bunlara ek işlevsellik eklemekten çekinirim. https://github.com/rails/activerecord-deprecated_finders –

cevap

5

basit cevap Object#method(:foo)Method bir örneğini döndürür genel yılında garanti etmek "hayır" -the tek yoludur nesne üzerinde foo adında bir yöntemi tanımlayan gereğidir.

s.t.'yi geçersiz kılarak, Object#method(:foo) örneğini Method örneğini geri döndürerek zorlayabilirsiniz. :foo verildiğinde true değerini döndürür. Örneğin:

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> 

(O yöntem aslında tanımlanmış olduğundan emin olmak için size kalmış): Gelecekte bu stumbles herkes için

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

Konuyla ilgili daha ayrıntılı bir blog yazısı: http://robots.thoughtbot.com/post/28335346416/always-define-respond-to-missing- ne zaman geçersiz kılınır – pje

+1

+1. Yani gerçekten Rails'in hatası çalışmıyor. Bu bakımdan düzeltmeye başladım, ör. https://github.com/rails/rails/pull/6169 –

+0

Tamam, bu mantıklı. Ve Marc-AndréLafortune, bu cevaba hemen cevap verdiğim sorumu cevapladın. :) İkinize de teşekkürler! –

İlgili konular