在 1.1 版本之前,自动销毁所有者自身销毁时的 has_many
关联的方法是在声明 has_many
时使用 :dependent
或 :exclusively_dependent
选项。
class Account < ActiveRecord::Base
has_many :members, :dependent => true
end
或
class Brand < ActiveRecord::Base
has_many :products, :exclusively_dependent => true
end
:依赖选项会实例化所有关联对象并在每一个对象上调用 destroy。destroy 又会触发该关联模型上定义的回调,例如使用 before_destroy
和 after_destroy
声明的回调。
另一方面,:exclusively_dependent
选项不会实例化所有关联对象。而是生成一条 SQL 语句,删除关联记录而不首先为它们创建对象。当您不需要触发模型回调的灵活性时,这可以提高效率。
自 1.1 版起,收集关联记录的垃圾的 API 已合并到 :dependent
选项中。现在,您不是说 :dependent => true
,而是将几个符号之一传递给 :dependent
选项,描述关联如何依赖于所有者。
声明 has many 为 :dependent => :destroy
与以前声明为 :dependent => true
相同。当所有者被销毁时,所有关联记录都会被实例化并销毁。
class Account < ActiveRecord::Base
# Deprecated
# has_many :members, :dependent => true
# In favor of
has_many :members, :dependent => :destroy
end
实现现在的已弃用的 :exclusively_dependent
配置的新方法是使用 :dependent => :delete_all
而不是 :dependent => :destroy
。
class Brand < ActiveRecord::Base
# Deprecated
# has_many :products, :exclusively_dependent => true
# In favor of
has_many :products, :dependent => :delete_all
end
命名 :destroy
和 :delete_all
选项符号是因为它们对应于在模型对象上调用 destroy
与调用 delete
实现的行为。一个触发回调,另一个只生成 delete SQL 语句。
顺便说一下,另一个有效的选项是 :dependent => :nullify
,它类似于 :dependent => :delete_all
,只是它不删除关联的记录,而是仅将其外键设置为 NULL
。这会有效地删除关联,而不会从数据库表中删除关联的记录。
与往常一样,:dependent => :destroy
和 :dependent => :delete_all
的语义是相互排斥的,新的 API 让这一点更加明显。
需要注意的是,在设置 has many 关联时,声明依赖项不是必需的。当您需要这种功能时,它只是一种选择。
请记住,目前仍然支持 :dependent => true
和 :exclusively_dependent => true
,但它们已被标记为已弃用,未来可能会被取代。