2012-09-22 4 views
5

私はUserという名前のRubyオブジェクト(特にActiveRecordオブジェクト)を持っています。 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

将来的にはこれにつまずき、誰のために、これらの動的ファインダーメソッドは、Railsの中で廃止される予定4.0。私は個人的にそれらの上に追加の機能を追加することに慎重になるだろう。 https://github.com/rails/activerecord-deprecated_finders –

答えて

5

最も簡単な答えは「ノー」Object#method(:foo)Methodのインスタンスを返すことを一般でを保証する-the唯一の方法は、オブジェクトにfooという名前のメソッドを定義することであるです。

Methodのインスタンスを返すように強制すると、Object#respond_to_missing? s.tを上書きすることができます。 :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、あなたは私の質問に答えました。私はすぐにこの答えに答えました。 :)あなたにおかげで両方! –

関連する問題