Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: how to disable before_destroy callback when it's being destroyed because of the parent is being destroyed (:dependent => :destroy)

Tags:

I have two classes: Parent and Child with

Child:

belongs_to :parent 

and

Parent

has_many :children, :dependent => :destroy 

The problem is that I want to check that there is always at least one child present, so I have a before_destroy method in Child that abort the destroy if it is the only child belonging to its parent.

And, if I want to destroy the parent, it will call the before_destroy callback on every child, but when there is one child, it will abort the destroy, so the parent will never get destroyed.

How can I tell the child to call the before_destroy callback only if it's not being destroyed because of its parent?

Thanks!

like image 565
Jose Valenzuela Demarco Avatar asked Jan 25 '12 09:01

Jose Valenzuela Demarco


People also ask

Why we use dependent destroy Rails?

dependent: :destroy Rails, when attempting to destroy an instance of the Parent, will also iteratively go through each child of the parent calling destroy on the child. The benefit of this is that any callbacks and validation on those children are given their day in the sun.

What is dependent destroy in Rails?

what is dependent :destroy. Dependent is an option of Rails collection association declaration to cascade the delete action. The :destroy is to cause the associated object to also be destroyed when its owner is destroyed.

What is prepend true in Rails?

:prepend — If true, the callback will be prepended to the existing chain rather than appended. In our case, with the user model we can see the callback order using _destroy_callbacks method : lambda in the callback chains are the dependent: :delete_all or dependent: :destroy before_destroy actions.

How do you destroy in Rails?

The standard way to delete associated data in Rails is to let ActiveRecord handle it via dependent: :destroy . In the following example, when the parent model ( author ) is deleted, all data in the dependent models will get deleted by ActiveRecord as well. There is an indexed foreign key, but no foreign key constraint.


2 Answers

In Rails 4 you can do the following:

class Parent < AR::Base   has_many :children, dependent: :destroy end  class Child < AR::Base   belongs_to :parent    before_destroy :check_destroy_allowed, unless: :destroyed_by_association    private    def check_destroy_allowed     # some condition that returns true or false   end end 

This way, when calling destroy directly on a child, the check_destroy_allowed callback will be run, but when you call destroy on the parent, it won't.

like image 90
Alexander Popov Avatar answered Sep 28 '22 22:09

Alexander Popov


has_many :childs, :dependent => :delete_all 

This will delete all the children without running any hooks.

You can find the documentation at: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

like image 35
Alex D Avatar answered Sep 29 '22 00:09

Alex D