【问题标题】:Rails - Delete all Records that Meet a ConditionRails - 删除所有符合条件的记录
【发布时间】:2012-10-10 18:27:59
【问题描述】:

您如何以 Rails 方式编写代码? 我有一个模型 - 经理。 我想删除Managers中满足manager_level为5的所有记录。

谢谢。

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    我认为使用destroy而不是delete更好

    因为destroy会从db中删除当前的对象记录以及它的 来自 db (https://stackoverflow.com/a/22757656/5452072) 的关联子记录

    delete 也会跳过回调,但 destroy 不会。

    Manager.where(:manager_level => 5).destroy_all
    

    【讨论】:

    • 绝对有效,但请记住:“通过实例化每条记录并调用其销毁方法来销毁匹配条件的记录。” (apidock.com/rails/ActiveRecord/Relation/destroy_all) 对于大型结果集,这可能会非常慢。
    • 是的,我正在考虑保持模型的一致性之类的东西。
    • @MurifoX - 你能解释一下为什么你认为销毁比删除更好吗?不一定不同意,但它会帮助你的答案更完整。
    • @PhilDD 我有同样的问题,我认为答案缺少为什么使用destroy_all而不是delete_all的原因。我在这里找到了答案:stackoverflow.com/a/22757533/5452072
    • destroy_all 和 delete_all 都有自己的位置。当您想快速删除 100k 条记录并且您知道没有回调或引用完整性问题时,destroy_all 永远不会有任何好处,而 delete_all 可以快速完成您想要的操作。当你想彻底删除 100 条记录并为它们进行所有 Rails 清理时,destroy_all 就是你想要的。
    【解决方案2】:

    试试这个:

    Manager.delete_all(manager_level: 5)
    

    【讨论】:

    • 1.我需要使用一个变量来指定要删除的内容。 2.该表没有索引,它是其他2个表之间的连接器表。
    • 对我不起作用。由于参照完整性而出现错误。
    • 这应该是公认的答案,因为其他查询尝试在删除之前选择 —— 导致大型数据集的性能问题。
    • 传递给delete_all/destroy_all的条件是removed in rails 5.1
    【解决方案3】:

    这应该可行:

    Manager.where(:manager_level => 5).delete_all
    

    注意:这不会删除相关记录。

    【讨论】:

      【解决方案4】:

      在 Rails 5.1. 之后,我们无法将条件传递给 delete_all/destroy_all 方法

      Manager.where(:manager_level => 5).delete_all
      

      这将运行多个查询以删除每条记录

      但是在Rails 6中,我们可以使用delete_by来删除使用条件,

      Manager.delete_by(manager_level: 5)
      

      这将运行单个删除查询

      delete from managers where manager_level = 5

      【讨论】:

      • 我不确定 Rails 6 model.delete_by(cond) 是否比 model.where(cond).delete_all 方法快。您可以看到 delete_by 在其原始分支上的实现似乎只是语法糖。 github.com/abhaynikam/rails/commit/…
      猜你喜欢
      • 2019-06-09
      • 1970-01-01
      • 2011-08-18
      • 2022-08-16
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      相关资源
      最近更新 更多