2012-09-22 43 views
5

Tôi có đối tượng Ruby (đối tượng ActiveRecord, cụ thể) có tên User. Nó phản hồi các phương thức như find_by_id, find_by_auth_token, v.v. Tuy nhiên, đây không phải là các phương pháp được xác định qua def hoặc define_method. Thay vào đó, chúng là các phương thức động được xử lý thông qua method_missing.Phương pháp # đối tượng và phản hồi động

Tôi muốn để có được một tham chiếu đến một trong những phương pháp thông qua Object#method, ví dụ .:

User.method(:find_by_auth_token) 

Nó không giống như các công trình này mặc dù. Giải pháp tốt nhất mà tôi đã đưa ra là:

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

Có cách nào khác để sử dụng phương pháp bao bọc như thế này không? Tôi thực sự không thể sử dụng Object#method cho các phương pháp động?

+2

cho bất cứ ai tình cờ về vấn đề này trong tương lai, những phương pháp cụ tìm động sẽ hết hạn vào Rails 4.0. Cá nhân tôi rất thận trọng khi thêm chức năng bổ sung vào đầu chúng. https://github.com/rails/activerecord-deprecated_finders –

Trả lời

5

Câu trả lời đơn giản nhất là "không" -the cách duy nhất để đảm bảo nói chung rằng Object#method(:foo) sẽ trả về một thể hiện của Method là bằng cách định nghĩa một phương thức có tên foo trên đối tượng.

Câu trả lời được chấp nhận nhiều hơn là bạn có thể ép buộc Object#method(:foo) trả lại phiên bản Method bằng cách ghi đè Object#respond_to_missing? s.t. nó trả về true khi được cấp :foo. Ví dụ:

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> 

(Đó là tùy thuộc vào bạn để đảm bảo rằng phương pháp này là thực sự xác định):

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

Dưới đây là bài đăng blog chuyên sâu hơn về chủ đề: http://robots.thoughtbot.com/post/28335346416/always-define-respond-to-missing- khi ghi đè – pje

+1

+1. Vì vậy, nó thực sự Rails 'lỗi nó không hoạt động. Tôi đã bắt đầu khắc phục sự cố đó, ví dụ: https://github.com/rails/rails/pull/6169 –

+0

Được rồi, điều đó có ý nghĩa. Và @ Marc-AndréLafortune, bạn đã trả lời câu hỏi của tôi rằng tôi ngay lập tức có phản ứng với câu trả lời này. :) Cảm ơn cả hai! –

Các vấn đề liên quan