ActiveRecord - 获取最后n条记录并在一个命令中删除它们?

时间:2014-01-15 07:31:04

标签: ruby rails-activerecord

大家好,感谢您抽出宝贵时间回答我的问题。

问题在标题中得到了解释。

我尝试了Model.last(n).destroy_all,但没有一个可行。

我想知道是否有可能在一行中完成,如果不是最干净的方法呢?

再次感谢!

2 个答案:

答案 0 :(得分:31)

这将删除一个SQL查询中的最后n条记录

Model.order('created_at DESC').limit(n).destroy_all

<强>更新: 更有效的方式是:

ids = Model.order('created_at DESC').limit(n).pluck(:id)
Model.where(id: ids).delete_all

虽然它不是一个命令,但它只执行2个SQL查询

答案 1 :(得分:7)

您可以通过以下方式实现这一目标:

Model.last(n).each(&:destroy)

@IvanDenisov指出了另一种方法:

Model.order('created_at DESC').limit(n).destroy_all

根据Rails API Doc,它基本上做同样的事情,但有点冗长。此外,它不能在一个SQL查询中完成所有操作。


SQL查询的详细比较

我尝试在Ruby 2.0.0p253&amp;&amp; Rails 4.0.4,结果如下:

rails console

2.0.0p353 :002 > Role.last(3).each(&:destroy) Role Load (1.0ms) SELECT "roles".* FROM "roles" ORDER BY "roles"."id" DESC LIMIT 3 (0.3ms) BEGIN SQL (3.5ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5487]] (11.8ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5488]] (5.4ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5489]] (4.6ms) COMMIT 2.0.0p353 :004 > Role.order('created_at DESC').limit(3).destroy_all Role Load (0.9ms) SELECT "roles".* FROM "roles" ORDER BY created_at DESC LIMIT 3 (0.2ms) BEGIN SQL (0.2ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5492]] (6.6ms) COMMIT (0.2ms) BEGIN SQL (0.2ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5491]] (0.4ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) DELETE FROM "roles" WHERE "roles"."id" = $1 [["id", 5490]] (0.2ms) COMMIT 部分完全相同。他们都进行了多次SQL查询。

唯一的区别是DELETE部分,如果我们将SELECT更改为'created_at DESC',它们也会完全相同