【问题标题】:How to preview a delete_all or destroy_all query in Rails如何在 Rails 中预览 delete_all 或 destroy_all 查询
【发布时间】:2012-06-07 16:52:13
【问题描述】:

你知道演习:生产数据库中弹出一些无效数据,你必须摆脱它。在生产服务器上启动 Rails 控制台并输入查询:

Foo.where(bar: 'baz').all

您查看了返回的数据,这就是您需要删除的数据。然后输入:

Foo.where(bar: 'baz').destroy_all

然后你的心跳停止了一秒钟。您只想在查询运行之前查看它。

在 Rails 中有什么方法可以做到这一点吗?我正在寻找类似于

的方法
Foo.where(bar: 'baz').to_sql

但是会返回 DELETE 查询的那个。

【问题讨论】:

    标签: ruby-on-rails activerecord arel


    【解决方案1】:

    问题是destroy_all 没有运行单个 SQL 查询。它遍历对象的散列,实例化它们,运行它们的回调,然后调用该对象的destroy 方法。 Rails 没有内置方法来生成这些查询的数组。

    Cdesroisiers 说得对,您可以在沙盒模式下测试查询,但真正的问题是,即使您已经验证了目标数据是什么,您仍然在猜测您是否决定运行 delete_all

    如果您不愿意相信 ActiveRecord 能够正确删除对象,请考虑使用 ActiveRecord 版本控制 gem,例如 PaperTrail

    【讨论】:

    • 不将delete_all 实现为批处理操作的理由是什么?我认为批量执行它比认真地往返数据库要便宜得多。
    • delete_all 是批处理操作。 destroy_all 一一进行。 delete_all 存在是因为它更快,destroy_all 很有用,因为它会在销毁回调之前/之后触发。
    • PaperTrail 非常适合在应用程序中使用,但我只需要删除一些冗余数据。还是谢谢!
    【解决方案2】:

    就在我的脑海中,您可以在沙盒模式下运行控制台并运行删除查询以查看 sql。更改只会在退出时回滚。

    【讨论】:

    • 如果您真的在寻找类似“to_sql”的命令,我想这并不能真正回答您的问题。
    • 我完全忘记了沙盒模式!这不完全是我想要的,但它完全符合我的需要。特别是考虑到我正在寻找的东西是不可能的:D
    【解决方案3】:

    destroy_all 方法和做的一样:

    Foo.where(bar: 'baz').each { |object| object.destroy }
    

    这样sql就变成了

    DELETE FROM foo WHERE foo.id = your_objects_id_attribute
    



    来自文档:

      def destroy_all(conditions = nil)
        find(:all, :conditions => conditions).each { |object| object.destroy }
      end
    

    【讨论】:

    • 我相信生成的 SQL 将包含多个 DELETE 查询 - 每个找到的对象一个。
    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2011-08-25
    • 2011-02-17
    • 2011-11-02
    相关资源
    最近更新 更多