Andrew W. wrote in post #1045018:
Fantastic to see some work being done on this, kudos to you! I have a
dumb
question. In the example in the readme, why can’t you just do
object.singleton_class.class_eval instead of object.class.class_eval?
That
should make the changes only affect that object, right?
Hehe, I think I should add this to the README…
Originally, that’s how I tried to use DCI with ActiveRecord. I tried
something like this:
module Poster
def self.extended(object)
object.singleton_class.class_eval do
after_save do
update_posts_or_something
end
end
end
def make_post
# blah, do something
end
end
user = User.find(1)
user.extend(Poster)
user.name = “Callie”
user.save
Well, it doesn’t work. ActiveSupport’s callbacks work by looking at the
object’s class for any defined callbacks, it never looks at the
singleton class.
The good news is that a single, one line change to ActiveSupport fixes
the problem. The bad news is that any object that has a singleton class
defined can’t be marshaled. The Rails core team doesn’t like that (a
long while ago I submitted a patch that passed all tests, but created
singleton classes on ActiveRecord instances… they accepted it
initially, but then backed it out once they found out about the
Marshaling issue).
I think one of the biggest downsides to not being able to marshal an
object is that you can’t cache it.
Ok, so regardless of the marshaling issue, let’s say getting callbacks
to work is as simple as that one line change to ActiveSupport. Great,
let’s move on to associations…
Long story short, it’s far from a one line change. Associations are
complicated, messy and magical.
I gave up trying to get object.singleton_class.class_eval(…) to work
with AS/AR and chose the approach you see in Schizo.
– C