I have been checking options of belongs_to method and testing following behavior in Rails 3.2.7
As per above link the :dependent
option states that
If set to :destroy, the associated object is destroyed when this object is. If set to :delete, the associated object is deleted without calling its destroy method.
As I understand the Author should be removed if Post is removed in following case:
class Post < ActiveRecord::Base
belongs_to :author, :dependent => :delete
end
class Author < ActiveRecord::Base
attr_accessible :name
has_one :post
before_destroy :log_author_removal
private
def log_author_removal
logger.error('Author is getting removed')
end
end
In console:
> Post.first
Post Load (0.4ms) SELECT "posts".* FROM "posts" LIMIT 1
=> #<Post id: 5, title: "Post 5", author_id: 3>
> p.delete
SQL (197.7ms) DELETE FROM "posts" WHERE "posts"."id" = 5
=> #<Post id: 5, title: "Post 5", author_id: 3>
> Author.find(3)
Author Load (0.5ms) SELECT "authors".* FROM "authors" WHERE "authors"."id" = ? LIMIT 1 [["id", 3]]
=> #<Author id: 3, name: "Author 3">
However calling p.destroy
deletes associated author.
Am I misunderstood above quoted statement?
What is the difference between :dependent => :destroy and :dependent => :delete_all in Rails? There is no difference between the two; :dependent => :destroy and :dependent => :delete_all are semantically equivalent.
If you set the :dependent option to: :destroy, when the object is destroyed, destroy will be called on its associated objects. :delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method.
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.
They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.
Yes, calling delete
generally skips all callbacks that either you or rails set on destroying the record. These include callbacks like before_destroy
and also destroying associated records.
Therefore if you call p.delete
it will not do anything with the associated records.
When you call p.destroy
it will:
before_destroy
callback if set.:dependent => :delete
, it will simply delete the Author object. If you set it to :destroy
it will repeat this whole process for the author object (callback & destroying its related records if applicable).after_destroy
callback if set.From what I understand :
:dependent => :destroy
will trigger association.destroy
if you call destroy
on the object.
:dependent => :delete
will trigger association.delete
if you call destroy
on the object.
In both cases, you have to call destroy
on the parent object. The difference lies in th methos that is called on the child object. If you don't want to trigger destroy filters on the child object use :dependent => :delete
. If you do want them, use :dependent => :destroy
.
By quickly taking a look at the source here : https://github.com/rails/rails/blob/357e288f4470f484ecd500954fd17fba2512c416/activerecord/lib/active_record/associations/builder/belongs_to.rb#L68
We see that calling dependent will just create an after_destroy on the parent model, calling either delete
or destroy
on the child object. But in both cases, it creates an after_destroy
.
belongs_to association support both :delete and :destroy for :dependent. you can refer below link http://apidock.com/rails/v4.0.2/ActiveRecord/Associations/ClassMethods/belongs_to
calling delete skips all callbacks like before_destroy and as well won't delete associated records for association object as well.
Example
class Order < ActiveRecord::Base
has_one :project, :dependent => :delete
has_many :resources, :dependent => :delete
end
class Project < ActiveRecord::Base
belongs_to :order, :dependent => :delete
end
In above code,if project has been destroyed then order will as well deleted but resources in order won't delete but if we use
belongs_to :order, :dependent => :destroy
then resources attached with orders as well deleted on project destroy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With