ruby-on-rails - 如何防止 has_and_belongs_to_many 删除选项删除 Rails 中正在使用的记录?

标签 ruby-on-rails ruby-on-rails-3 activerecord has-and-belongs-to-many

class Assembly < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :assemblies
end

在控制台中:

part1 = Part.new
assembly1 = Assembly.new
assembly1.parts << part1
part1.delete
Parts.all
 => []

检查 assembly1.parts 表明仍然存在关系。(!)

当记录被删除时怎么可能呢?

此外,如何防止删除与装配体关联的零件?

使用 Rails 3.0.7。

最佳答案

您在这里所做的一切都是根据内存完成的(数据库中没有存储任何内容)。

ActiveRecord delete 方法将从数据库中删除一个对象,但它不会在内存中查找可能已经引用该对象的其他对象。我认为如果您执行 assembly1.parts.delete(part1) ,这可能会达到您的预期。

如果您已将对象保存到数据库:

part1 = Part.create
assembly1 = Assembly.create(:parts => [part1])
assembly1.parts
# => [part1]
part1.delete
assembly1.parts
# => [part1]
assembly1.reload
assembly1.parts
# => []

请注意,即使它位于数据库中 part1.delete 也不一定会将其从程序集对象中删除,直到您刷新内存中集合或使用我之前提到的方法删除它 assembly1.parts.delete(part1)

更新

我认为您通常不应该使用delete()方法。您几乎应该始终使用destroy()delete() 只会触发对数据库的删除并忽略所有回调,我相信模型中的 :dependent => :destroy 样式声明。如果您使用 destroy() 方法,那么您可以在模型中声明 before_destroy 回调:

class MyClass
  has_and_belongs_to_many :foos

  before_destroy :allow_destroy

  def allow_destroy
    foos.empty?
  end
end

如果它是程序集的一部分,这应该满足您不破坏它的要求。您无法阻止 delete() 执行,因为它会忽略回调:ActiveRecord::Relation#delete documentation

有关 model callbacks (documentation) 的更多信息

关于ruby-on-rails - 如何防止 has_and_belongs_to_many 删除选项删除 Rails 中正在使用的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10096000/

相关文章:

jquery - 添加 Jquery 脚本标签

javascript - 在另一个模板的元素上引发单击事件

ruby-on-rails - rails3 中带有 date_select 的 form_tag

ruby-on-rails - 如何在 ruby​​ on rails 中以多对多关系对对象进行排序?

javascript - TypeError : document. 观察不是一个函数

ruby-on-rails - 通过指定其 "id"(而不是通过其父级查找)来销毁嵌入的 Mongoid 文档

mysql - 带有 CASE 和 WHEN 的 Ruby update_all

ruby-on-rails - 如何在 Rails 中使用 ruby​​-progressbar?

ruby-on-rails - ActiveJob 序列化 : no call to deserialize

ruby-on-rails - 获取每组最新的n条记录