Ruby-on-rails :dependent => :delete onbelongs_to 不会删除所有者对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12458662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:46:08  来源:igfitidea点击:

:dependent => :delete on belongs_to doesn't delete owner object

ruby-on-railsruby-on-rails-3activerecord

提问by Amit Patel

I have been checking options of belongs_tomethod and testing following behavior in Rails 3.2.7

我一直在检查belongs_to方法的选项并测试Rails 3.2.7中的以下行为

As per above link the :dependentoption states that

根据上面的链接,该:dependent选项指出

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.

如果设置为:destroy,当这个对象被销毁时,关联的对象被销毁。如果设置为 :delete,关联的对象将被删除而不调用它的 destroy 方法。

As I understand the Author should be removed if Post is removed in following case:

据我了解,如果在以下情况下删除 Post,则应删除作者:

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.destroydeletes associated author.

但是调用p.destroy会删除相关作者。

Am I misunderstood above quoted statement?

我是否误解了上面引用的声明?

回答by Jakub Hampl

Yes, calling deletegenerally skips all callbacks that either you or rails set on destroying the record. These include callbacks like before_destroyand also destroying associated records.

是的,调用delete通常会跳过您或 rails 在销毁记录时设置的所有回调。这些包括回调before_destroy和销毁相关记录。

Therefore if you call p.deleteit will not do anything with the associated records.

因此,如果您调用p.delete它,它将不会对关联的记录执行任何操作。

When you call p.destroyit will:

当你调用p.destroy它时:

  1. Call the before_destroycallback if set.
  2. Delete the object.
  3. If you set :dependent => :delete, it will simply delete the Author object. If you set it to :destroyit will repeat this whole process for the author object (callback & destroying its related records if applicable).
  4. Call the after_destroycallback if set.
  1. before_destroy如果设置,则调用回调。
  2. 删除对象。
  3. 如果你设置了:dependent => :delete,它只会删除 Author 对象。如果您将其设置为:destroy它将为作者对象重复整个过程(如果适用,回调并销毁其相关记录)。
  4. after_destroy如果设置,则调用回调。

回答by Anthony Alberto

From what I understand :

据我了解:

:dependent => :destroywill trigger association.destroyif you call destroyon the object.

:dependent => :destroyassociation.destroy如果您调用destroy对象,将触发。

:dependent => :deletewill trigger association.deleteif you call destroyon the object.

:dependent => :deleteassociation.delete如果您调用destroy对象,将触发。

In both cases, you have to call destroyon 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.

在这两种情况下,您都必须调用destroy父对象。不同之处在于在子对象上调用的方法。如果您不想在子对象上触发销毁过滤器,请使用:dependent => :delete. 如果您确实需要它们,请使用: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

通过快速查看这里的源代码: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 deleteor destroyon the child object. But in both cases, it creates an after_destroy.

我们看到,在调用依赖只会创建父模型的after_destroy,无论是打电话deletedestroy子对象。但在这两种情况下,它都会创建一个after_destroy.

回答by Vaibhav

belongs_to association support both :deleteand :destroyfor :dependent. you can refer below link http://apidock.com/rails/v4.0.2/ActiveRecord/Associations/ClassMethods/belongs_to

对于:dependent ,belongs_to 关联同时支持:delete:destroy。您可以参考以下链接 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.

调用 delete 会跳过所有回调,例如 before_destroy,并且也不会删除关联对象的关联记录。

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.

然后与订单相关的资源以及在项目销毁时删除。

回答by TheIrishGuy

 belongs_to :author, :dependent => :delete

Should be: belongs_to :author, :dependent => :destroy

应该是:belongs_to :author, :dependent => :destroy

:destroy and :delete behave differently in ActiveRecord, delete bypasses validations and AR associations, thus associated objects are not being removed.

:destroy 和 :delete 在 ActiveRecord 中的行为不同,删除绕过验证和 AR 关联,因此不会删除关联的对象。

回答by Mohanraj

belongs_to association can't support the :deletefor :depedent. It supports only :destroy. Please refer this link http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html.

own_to 关联不能支持:delete:depedent。它只支持:destroy。请参阅此链接http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html