17

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

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

如果设置为 :destroy,则关联对象在该对象被销毁时被销毁。如果设置为 :delete,则删除关联对象而不调用其 destroy 方法。

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

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

在控制台中:

> 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"> 

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

我是否误解了上面引用的陈述?

4

5 回答 5

25

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

因此,如果您调用p.delete它,它将不会对关联的记录做任何事情。

当您调用p.destroy它时,它将:

  1. 如果设置,则调用before_destroy回调。
  2. 删除对象。
  3. 如果您设置:dependent => :delete,它将简单地删除 Author 对象。如果将其设置为:destroy它将为作者对象重复整个过程(如果适用,则回调和销毁其相关记录)。
  4. 如果设置,则调用after_destroy回调。
于 2012-09-17T12:05:21.740 回答
7

据我了解:

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

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

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

通过快速查看这里的源代码:https ://github.com/rails/rails/blob/357e288f4470f484ecd500954fd17fba2512c416/activerecord/lib/active_record/associations/builder/belongs_to.rb#L68

我们看到调用dependent 只会在父模型上创建一个after_destroy,调用其中一个deletedestroy子对象。但在这两种情况下,它都会创建一个after_destroy.

于 2012-09-17T12:24:22.677 回答
2

belongs_to 关联同时支持:delete:destroy用于:dependent。您可以参考以下链接 http://apidock.com/rails/v4.0.2/ActiveRecord/Associations/ClassMethods/belongs_to

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

例子

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

在上面的代码中,如果项目已被销毁,那么订单也会被删除,但订单中的资源不会被删除,但如果我们使用

belongs_to :order, :dependent => :destroy

然后附加订单的资源以及项目销毁时删除。

于 2014-08-30T13:56:32.660 回答
1
 belongs_to :author, :dependent => :delete

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

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

于 2012-09-17T12:01:26.160 回答
-1

belongs_to 关联不支持: depedent的:delete。它仅支持:destroy。请参考此链接http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

于 2012-09-17T12:06:00.540 回答