I wrote a convenience ActiveRecord extension to delegate methods to a base object (based on multi-table inheritance)
class ActiveRecord::Base
def self.acts_as(base)
class_eval %Q{
def method_missing(method, *args, &blk)
#{base}.send(method, *args, &blk)
rescue NoMethodError
super
end
}
end
end
I have a state class and a base class
# state class class MyState < ActiveRecord::Base belongs_to :my_object acts_as :my_object end # base class class MyObject < ActiveRecord::Base has_one :head, :class_name => 'MyState' has_one :tail, :class_name => 'MyState' end
When I tried this out, I found out that it doesn’t work in some cases. More specifically,
> MyState.first.some_method_in_base nil > MyObject.first.tail.some_method_in_base NoMethodError: undefined method `some_method_in_base' for #<ActiveRecord::Associations::HasOneAssociation:0xABCDEFG>
Can anyone enlighten me as to why one works and the other doesn’t?
When you run
MyObject.first.tailthe object that actually responds is an AssociationProxy class thatYou can get more details about the proxy running:
If you look in the code, you can see that the AssociationProxy proxies the method some_method_in_base to your MyState class only if MyState responds to some_method_in_base as you can see in the code below.
Therefore, the method_missing you have defined in the target class is never called.