Forum: Ruby on Rails Improve(?) has_many :dependent => :destroy before destroy callback

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
984e68287c499e1fcf7606a8e6698f03?d=identicon&s=25 Michal Pokrywka (mpokrywka)
on 2009-02-03 22:40
(Received via mailing list)
Hi,
I tried to submit this via lighthouse, but after third POST failure
(mail also failed) I thought maybe someone here will be interested and
forward this further.

In my application I have dependent models and I wanted to use
before_destroy callback to "validate" if dependent item could be
destroyed:

@@@
class Squad < ActiveRecord::Base
 has_many :trolls, :dependent => :destroy
end

class Troll < ActiveRecord::Base
 belongs_to :squad
 before_destroy :destroy_cb

 def destroy_cb
   # I am indestructible!
   false
 end
end
@@@

Trying to destroy troll fails as expected, but when I destroy Squad,
it is disbanded but members are still alive, go berserk and trash my
database (foreign key points to invalid - removed - squad).
When I command "Squad.first.destroy" I expect failure because my
minions are indestructible - dependent-destroy should fail.

I propose following change: try to destroy all dependent items - as it
is done now - then: if any dependent destroy operation failed, return
failure and do not progress further.

(patch inline)
--- activerecord-2.2.2/lib/active_record/associations.rb.orig
2009-02-03 17:29:13.000000000 +0100
+++ activerecord-2.2.2/lib/active_record/associations.rb  2009-02-03
17:30:49.000000000 +0100
@@ -1452,7 +1452,7 @@
               when :destroy
                 method_name = "has_many_dependent_destroy_for_#
{reflection.name}".to_sym
                 define_method(method_name) do
-                  send(reflection.name).each { |o| o.destroy }
+                  send(reflection.name).map { |o| o.destroy }.all?
                 end
                 before_destroy method_name
               when :delete_all
This topic is locked and can not be replied to.