2012-09-22 31 views
5

我有一個名爲User的Ruby對象(特別是ActiveRecord對象)。它響應了諸如find_by_id,find_by_auth_token等方法。但是,這些不是通過defdefine_method定義的方法。相反,它們是通過method_missing處理的動態方法。對象#方法和動態響應器

我想通過Object#method獲取到的這些方法中的一種參考,例如:

User.method(:find_by_auth_token) 

它看起來並不像這個作品雖然。我提出的最佳解決方案是:

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

是否有任何其他解決方法使用這種包裝方法?我真的無法使用動態方法Object#method

+2

任何人誰在未來這個失蹄,這些動態finder方法將在Rails中被棄用4.0。我個人會謹慎地在其上增加額外的功能。 https://github.com/rails/activerecord-deprecated_finders –

回答

5

最簡單的答案是「不」,以保證一般Object#method(:foo)將返回Method實例-The唯一方法是定義一個名爲foo的對象方法。

更復雜的答案是,你可以通過覆蓋Object#respond_to_missing? s.t.強制Object#method(:foo)返回Method的實例。當給出: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。所以這真的是Rails的錯,它不起作用。我已經開始在這方面進行修復,例如https://github.com/rails/rails/pull/6169 –

+0

好的,這是有道理的。而@ Marc-AndréLafortune,你回答了我的問題,我立即迴應了這個答案。 :)謝謝你們兩位! –