Rails:删除级联vs依赖destroy

时间:2012-09-23 21:58:41

标签: ruby-on-rails postgresql referential-integrity

假设我有两个表:usersorders。用户有很多订单,所以我的订单表中自然会有一个外键user_id。

rails中的最佳做法(速度,样式和参照完整性)是什么,以确保删除用户时,所有相关订单也会被删除?我正在考虑以下选项:

案例1.在用户模型中使用:dependent => :destroy

案例2.在postgres中定义表格订单并编写

user_id integer REFERENCES users(id) ON DELETE CASCADE

为什么我应该使用案例1?似乎案例2正在做我想做的一切吗?执行速度方面有区别吗?

3 个答案:

答案 0 :(得分:29)

这实际上取决于你想要的行为。在案例1中,将在每个关联订单上调用destroy,因此ActiveRecord callbacks也是如此。在案例2中,这些回调不会被触发,但会更快,并保证参照完整性。

在应用程序的初期,我建议使用:dependent => :destroy,因为它让您以独立于数据库的方式开发。一旦开始扩展,您应该出于性能/完整性原因在数据库中开始这样做。

答案 1 :(得分:18)

has_many :orders, dependent: :destroy

  • 自动维护数据完整性的最安全选项。
  • 您具有多态关联,并且不想使用触发器。


add_foreign_key :orders, :users, on_delete: :cascade(在数据库迁移中)

  • 您没有使用任何多态关联,或者您希望为每个多态关联使用触发器。


has_many :orders, dependent: :delete_all

  • 仅当has_many是关联树上的叶节点时才使用(即,子节点没有与外键引用的另一个has_many关联)

答案 2 :(得分:6)

我会使用选项1.虽然它可能有用,但我可以看到选项2的一些问题:

  1. ActiveRecord将不知道这些记录被删除了 可能导致行为不稳定
  2. 任何阅读该代码的人都不清楚删除用户意味着他们的所有订单也将被删除
  3. 订单上的任何destroy处理程序都不会触发
  4. 当然,我希望选项2更快,但如果权衡价值,这取决于你。删除用户是否是应用程序中的常见操作?

    另一种选择是使用:dependent => :delete_all。这将比:dependent => :destroy更快,并避免上面的缺点1和2。有关详细信息,请参阅here