
A lot of funkiness going on with Hooks and dm-more
Reported by Carl Lerche | June 11th, 2008 @ 05:55 PM
Alright, I will try to explain this as best as I can. First, let me start by explaining how I came across this bug.
I created a simple model in Merb and I required dm-validations. All is good. I can save my model and specify the context ( User.new.save(:default) ).
Ok, now I decide that I would like to have the dm-timestamps extension. I require dm-timestamps BEFORE dm-validations.
All of a sudden, I have the OLD #save method (without validations). However, all the other methods from the Validation module are present. I can still do User.new.valid?
Funkiness!!!!
So, I decided to do some digging. I isolated the problem to line #33 in dm-timestamps.rb (model.before :save, :set_timestamp_properties).
It turns out that there is a bug with declaring instance hooks inside a def self.included(base) method. I believe that this method is run BEFORE the module is actually included (at least, before the class that is including the module has the methods defined in it). Now, I checked out the Hook code and hooks work by redefining the method that is being hooked (seems a bit fishy to me). In other words, the method that is being hooked is being redefined before it is actually defined by a module that is being included... or something.
I'm not exactly sure what it is, but it smells fishy.
Personally, I don't get why Hook is coded as is instead of something simpler where callbacks are explicitly invoked. It seems pretty complicated as is.
Comments and changes to this ticket
-
-
Carl Lerche June 11th, 2008 @ 09:51 PM
Check out this little bit of code. It demos why the bug happens.
#!/usr/bin/env ruby module FirstModule def self.included(base) base.class_eval %{ def test "world" end } base.class_eval { include SecondModule } end end module SecondModule def test "hello" end end class MyClass include FirstModule end # Will put "world". Hook assumes it will put "hello" puts MyClass.new.test
Basically, dm-timestamp adds a before save Hook when included (using class_eval and rewriting the method being hooked) and dm-validations tries to include a new version of save so the dm-validations save method is completely lost.
-
Carl Lerche June 11th, 2008 @ 11:18 PM
Welp, I think I figured the problem out and I created a patch and spec.
-
Adam French June 12th, 2008 @ 10:48 AM
- State changed from new to resolved
I just applied the patch and it works like a charm. Thanks a bunch carl!
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
People watching this ticket
Attachments
Referenced by
-
343 problem with before :save and newly created objects Is this related to the bug I just reporte? #371
-
367 interference with dm-timestamps and dm-validations I'm pretty sure that this is a duplicate of #371 (well, ...
-
343 problem with before :save and newly created objects I really believe that this is related to #371, which I f...