Feb 13, 2009

DataMapper destroy! hook

I was working on a project this week, I just found out, in DM association, parent.children.destroy! bypasses the child's before :destry hook, here is example:
#I am not sure if this is the feature(it is designed to do so),
# or I'm doing it wrong. Here is the situation I have:
# as of DM version: 0.9.9
class Order
before :destroy, :destroy_items
....
has n, items ...
def destroy_items
# NOT working
# this by pass the item's before destroy hook
# items.destroy!
# this part is working, the :check_xxx is called
items.each |item| do
...
item.destroy
end
end
end
class OrderLineItem
...
before :destroy, :check_xxx
belongs_to :order
def check_xxx
raise "the_error_message" if xxxxx
end
end


I also noticed that there is a plugin dm-constraints, I haven't check it out yet, but it seems like the same, here is the code from the plugin:
# from dm-constraints/lib/dm-constraints/delete_constraint.rb
when :destroy!
if children
# not sure why but this lazy_load is necessary
# otherwise children will not be deleted with destroy!
children.lazy_load
children.destroy!
end
....


I filed an issue report on lighthouseapp.com.

UPDATE(Feb-21-2009): Just got the note from Dan Kubb( one of the core DM developers):
"The Collection#destroy! method is actually supposed to bypass all hooks. The way you're doing it by looping over the records and calling each Resource#destroy method is the proper approach to execute each Resources' hooks.
In dm-core 0.10.0 there will be a Collection#destroy method that wraps this up and essentially does the same thing."

This makes a lot of sense. Like always, I really appreciate the attitude of the developers from DM, that is one one the reason I am using DM.

No comments: