Sometime ago while using method_missing
to implement some functionality I got the weird behavior that it would work only
most of the time but not always.
In retrospect it’s now pretty obvious but in the heat of the moment it took me about half a day of investigation and talking
before I figured it out.
What happened is that I did only half of the work.
I defined method_missing
but I forgot to define respond_to?
accordingly.
The result is that it worked when I called it directly on the instance, but failed if an association was involved.
To give an example, say you have a class like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Calling example directly on your instance works just fine.
1 2 3 4 5 |
|
All fine, but as soon as you get an association in the middle of things:
1 2 3 |
|
It just doesn’t go well anymore:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Now, this last error is a bit clearer but I don’t remember running into it at the time.
If I had just followed the association_proxy:220 hint right away… ;)
What happens is that b.a
doesn’t return the instance but rather an AssociationProxy instance that provides ActiveRecord’s
extended functionality and this proxy relies on A#respond_to?
to correctly forward method calls to the actual instance.
What I should have done is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 |
|
There are some much better write-ups on this topic, if you want to read more:
- Using method_missing and respond_to? to create dynamic methods
- Solving the method_missing/respond_to? problem
Now, I must be honest here: what I was doing was a big code smell :)
It taught me the lesson to use method_missing properly and was even quite fun to debug and all that but what I really needed and
end up doing in that case was a group of delegates here and there and voilà, it was all cool and clean.