级联删除Ruby ActiveRecord模型?

时间:2020-12-29 18:05:25

I was following the screencast on rubyonrails.org (creating the blog).

我正在跟踪rubyonrails.org(创建博客)上的截图。

I have following models:

我有以下模型:

comment.rb

comment.rb

class Comment < ActiveRecord::Base
    belongs_to :post
    validates_presence_of :body # I added this
end

post.rb

post.rb

class Post < ActiveRecord::Base
    validates_presence_of :body, :title
    has_many :comments
end

Relations between models work fine, except for one thing - when I delete a post record, I'd expect RoR to delete all related comment records. I understand that ActiveRecords is database independent, so there's no built-in way to create foreign key, relations, ON DELETE, ON UPDATE statements. So, is there any way to accomplish this (maybe RoR itself could take care of deleting related comments? )?

模型之间的关系很好,除了一件事——当我删除一个post记录时,我期望RoR删除所有相关的评论记录。我知道ActiveRecords是独立于数据库的,所以没有内置的方法来创建外键、关系、删除、更新语句。那么,有什么方法可以实现这一点(也许RoR本身可以处理删除相关的注释吗?)

1 个解决方案

#1


78  

Yes. On a Rails' model association you can specify the :dependent option, which can take one of the following three forms:

是的。在Rails的模型关联中,您可以指定:dependent选项,它可以采用以下三种形式之一:

  • :destroy/:destroy_all The associated objects are destroyed alongside this object by calling their destroy method
  • :销毁/:销毁所有关联的对象,并通过调用它们的销毁方法与此对象一起销毁。
  • :delete/:delete_all All associated objects are destroyed immediately without calling their :destroy method
  • :delete/:delete_all关联对象立即被销毁,而不调用它们的:destroy方法
  • :nullify All associated objects' foreign keys are set to NULL without calling their save callbacks
  • :将所有关联对象的外键设置为NULL,而不调用它们的save回调

Note that the :dependent option is ignored if you have a :has_many X, :through => Y association set up.

注意:如果设置了:has_many X,:through => Y关联,则忽略:dependent选项。

So for your example you might choose to have a post delete all its associated comments when the post itself is deleted, without calling each comment's destroy method. That would look like this:

因此,对于您的示例,您可以选择在删除post时让post删除所有相关的注释,而不调用每个注释的销毁方法。看起来是这样的:

class Post < ActiveRecord::Base
  validates_presence_of :body, :title
  has_many :comments, :dependent => :delete_all
end

Update for Rails 4:

In Rails 4, you should use :destroy instead of :destroy_all.

在Rails 4中,应该使用:destroy而不是:驱逐舰_all。

If you use :destroy_all, you'll get the exception:

如果您使用:驱逐舰_all,您将获得异常:

The :dependent option must be one of [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception]

从属选项必须是[:destroy,:delete_all,:nullify,: limitt_with_error,: limitt_with_exception]

#1


78  

Yes. On a Rails' model association you can specify the :dependent option, which can take one of the following three forms:

是的。在Rails的模型关联中,您可以指定:dependent选项,它可以采用以下三种形式之一:

  • :destroy/:destroy_all The associated objects are destroyed alongside this object by calling their destroy method
  • :销毁/:销毁所有关联的对象,并通过调用它们的销毁方法与此对象一起销毁。
  • :delete/:delete_all All associated objects are destroyed immediately without calling their :destroy method
  • :delete/:delete_all关联对象立即被销毁,而不调用它们的:destroy方法
  • :nullify All associated objects' foreign keys are set to NULL without calling their save callbacks
  • :将所有关联对象的外键设置为NULL,而不调用它们的save回调

Note that the :dependent option is ignored if you have a :has_many X, :through => Y association set up.

注意:如果设置了:has_many X,:through => Y关联,则忽略:dependent选项。

So for your example you might choose to have a post delete all its associated comments when the post itself is deleted, without calling each comment's destroy method. That would look like this:

因此,对于您的示例,您可以选择在删除post时让post删除所有相关的注释,而不调用每个注释的销毁方法。看起来是这样的:

class Post < ActiveRecord::Base
  validates_presence_of :body, :title
  has_many :comments, :dependent => :delete_all
end

Update for Rails 4:

In Rails 4, you should use :destroy instead of :destroy_all.

在Rails 4中,应该使用:destroy而不是:驱逐舰_all。

If you use :destroy_all, you'll get the exception:

如果您使用:驱逐舰_all,您将获得异常:

The :dependent option must be one of [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception]

从属选项必须是[:destroy,:delete_all,:nullify,: limitt_with_error,: limitt_with_exception]