我可以在Rails中设置Cascade删除吗?

mat*_*dev 79 ruby database ruby-on-rails

我知道这可能是在互联网上的某个地方,但我在Stackoverflow上找不到答案,所以我想我可以在这里增加一点知识库.

我是Ruby和Rails的新手,但是我的公司正在投入大量资金,所以我试图更详细地了解它.

我很难将我的思维方式转变为从"模型"而不是从数据库设计应用程序,所以我试图弄清楚如何在数据库中完成我在数据库中所做的所有设计工作. Rails模型代替.

所以我自己最近的任务是弄清楚如何配置Rails数据库模型来进行级联删除?有这么简单的方法吗?或者我是否必须进入MySql并进行设置?

Mik*_*een 95

您还可以将:dependent选项设置为:delete_all.:delete_all将发出单个SQL语句来删除所有子记录.因为这个使用:delete_all可能会给你更好的性能.

has_many :memberships, dependent: :delete_all
Run Code Online (Sandbox Code Playgroud)

  • 确保你理解使用`:delete_all`和`:destroy`之间的区别.两者都会导致子成员资格(删除[引用需要1级]和销毁的'n`(如果他们的孩子有依赖性破坏))从数据库中删除,但`:destroy`将实例化每个子对象并运行任何回调首先,``delete_all`将直接在数据库中运行SQL DELETE语句.`:destroy`因此而变慢,但它允许你在销毁记录时进行回调.在一端规避Rails,在另一端规避潜在的n ^ x实例化. (25认同)
  • 你的解释令人困惑.将使用单个SQL语句,但不会为每个子行调用destroy方法.你必须使用destroy_all. (8认同)
  • 我建议还设置数据库外键。这样,一次操作就可以删除记录。请参阅我发布的以下答案。 (2认同)

dan*_*yer 66

是的,你可以,如果你正在使用像has_many这样的关系你就是这么做的

has_many :memberships, dependent: :destroy
Run Code Online (Sandbox Code Playgroud)


Hen*_*rik 20

与提供的答案相反,我强烈建议在数据库级别上执行此操作.如果您有不同的进程或多线程环境,则可能会发生未正确删除记录的情况.此外,数据库外键在删除大量数据时会更快.

像建议的答案一样做:

has_many :memberships, dependent: :delete_all
Run Code Online (Sandbox Code Playgroud)

但是也要确保foreign_key在迁移中设置a .这样,数据库就会自动为您删除记录.

要在删除成员资格时使值无效,假设您有一个用户模型:

add_foreign_key :users, :memberships, on_delete: :nullify
Run Code Online (Sandbox Code Playgroud)

删除成员资格时,您也可以删除所有模型

add_foreign_key :users, :memberships, on_delete: :cascade
Run Code Online (Sandbox Code Playgroud)

  • 我很好奇你们俩都发生时会发生什么。似乎它不应该产生负面影响,但是有人在进行AR和DB级别的实践方面有不好的经验吗? (3认同)
  • 您甚至不需要在模型中设置`delete_all`.外键将负责在数据库级别为您正确删除所有内容. (2认同)

Jar*_*dom 10

请记住,delete_all不会对子记录执行任何回调(如before_destroy和after_destroy).


Sea*_*ins 6

如果您希望在实际数据库结构中反映出级联删除,看起来这个插件可能会为您提供所需内容:

http://www.redhillonrails.org/foreign_key_migrations.html

在迁移中使用它的格式如下:

create_table :orders do |t|
  t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade
  ...
end
Run Code Online (Sandbox Code Playgroud)

  • 这个链接已经死了,但这是一个更新的选择:http://github.com/matthuhiggins/foreigner (5认同)