I wanted to do:
foo.wrap
and wrap would go to a specialized wrap for some types of foo and a general Object#wrap for all the others.
So I added wrap to Object
class Object def wrap self end end
This worked except for objects which are actually AssociationProxy objects pretending to be some other object. The reason is that AssociationProxy removes all but a few methods from itself. You will find this line at the top of vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_)/ }
This happens before the files in initializers gets loaded. And that is where I added Object#wrap. So, for a proxied object, it would call Object#wrap instead of the specialized wrap that I had defined in my class.
My solution to this was to do this:
module ActiveRecord module Associations class AssociationProxy undef_method :wrap undef_method :unwrap end end end
I *think* Rails could solve this problem by hooking into Object.method_added. And when methods are added, the hook could undef them for the proxy class(es). The other choice would be to subclass AssociationProxy from BlankSlate rather than Object -- it appears that that is what BlankSlate is intended to do.