Karl
2009-Nov-11 08:30 UTC
AR Association Proxy prevents calling methods defined using method_missing on the target of the association
HI all, I''ve created a ticket https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3481-ar-association-proxy-prevents-calling-methods-defined-using-method_missing-on-the-target-of-the-association for this problem and a patch if someone would like to pick it up. Is this the correct procedure for assigning a ticket? :P From the commit: Don''t raise a NoMethodError if the target does not respond_to? method. This excludes methods on target that are implemented using method_missing. And if the method really doesn''t exist, target.send (method, args) will raise a NoMethodError itself...so let it do that. Description: If I have a model like this: class User < ActiveRecord::Base # Provide is_admin?, is_guest? account type discovery methods def method_missing(method_id, *arguments) if match = /^is_(\w+)\?$/.match(method_id.to_s) self.account_type == match[1] else super end end end class Activity < ActiveRecord::Base belongs_to :user end I can''t do Activity.first.user.is_guest? because it raises a NoMethodError. The problem is that the Association Proxy only allows calling methods on the target that respond_to?(method). It doesn''t need to do this check, because if the method really doesn''t exist, the call to target.send(method, args) will raise NoMethodError itself, so nothing is gained by doing that check in the proxy. Regards, Karl -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=.
Michael Koziarski
2009-Nov-19 03:24 UTC
Re: AR Association Proxy prevents calling methods defined using method_missing on the target of the association
> If I have a model like this: > > class User < ActiveRecord::Base > # Provide is_admin?, is_guest? account type discovery methods def > method_missing(method_id, *arguments) > if match = /^is_(\w+)\?$/.match(method_id.to_s) > self.account_type == match[1] > else > super > end > > end end >If you override method_missing, you need to also override respond_to?> > I can''t do Activity.first.user.is_guest? because it raises a > NoMethodError. The problem is that the Association Proxy only allows > calling methods on the target that respond_to?(method). It doesn''t > need to do this check, because if the method really doesn''t exist, the > call to target.send(method, args) will raise NoMethodError itself, so > nothing is gained by doing that check in the proxy.This is not quite right. send will also call private methods, the proxy check prevents that.> Regards, > Karl > > -- > > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=. > >-- Cheers Koz -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=.