My current code:
class Product < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
def method_missing name
true
end
end
Category.new.ex_undefined_method #=> true
Product.last.category.ex_undefined_method #=> NoMethodError: undefined method `ex_undefined_method' for #<ActiveRecord::Associations::BelongsToAssociation:0xc4cd52c>
This happens because of this code in rails which only passes methods that exist to the model.
private
def method_missing(method, *args)
if load_target
if @target.respond_to?(method)
if block_given?
@target.send(method, *args) { |*block_args| yield(*block_args) }
else
@target.send(method, *args)
end
else
super
end
end
end
This is what I want:
Product.last.category.ex_undefined_method #=> true
How can I accomplish this?
Note that the AssociationProxy
object only sends on methods that the target claims to respond_to?
. Therefore, the fix here is to update respond_to?
as well:
class Category < ActiveRecord::Base
def method_missing(name, *args, &block)
if name =~ /^handleable/
"Handled"
else
super
end
end
def respond_to?(name)
if name =~ /^handleable/
true
else
super
end
end
end
In fact, you should always update respond_to?
if you redefine method_missing
- you've changed the interface of your class, so you need to make sure that everyone knows about it. See here.