Rails会破坏所有最新的n条记录

如何使用Rails的ActiveRecord销毁除最新的n条记录之外的所有记录?

我可以使用顺序和限制获得最新的n条记录但是如何销毁反转?

这些方法中的任何一种都可以做到:

# Fetch your latest N records newest_n_records = Foo.find(:all, :order => 'created_at DESC', :limit => n) # Then do: Foo.destroy_all(['id NOT IN (?)', newest_n_records.collect(&:id)]) # Or: Foo.destroy_all('created_at < ?', newest_n_records.last.created_at) 

我有两种方法可以做到这一点,假设n = 5:

 Foo.order('id desc').offset(5).destroy_all 

这会先记录最新的记录,然后销毁第5条记录以外的所有内容。 要么

 Foo.destroy_all(['id <= ?', Foo.order('id desc').limit(1).offset(5).first.id]) 

这将找到第6个最新记录ID并删除id <=第6个最新记录ID的所有记录。

此外,您可能想看看这个问题 。

 Foo.destroy_all(['id NOT IN (?)', Foo.last(1000).collect(&:id)]) 

Person.destroy_all("last_login < '2004-04-04'")

这将摧毁所有符合条件的人。 所以你需要的只是倒置条件和destroy_all

以前的答案使用findlast需要创建ActiveModel,这需要额外的计算时间。

我认为使用pluck更好,因为它只创建一个id数组。

 ids = Foo.limit(n).order('id DESC').pluck(:id) Foo.where('id NOT IN (?)', ids).destroy_all 

[Rails 5 / ActiveRecord :: Relation]

destroy_all不再需要参数……实际上,ActiveRecord :: Relation从不允许参数我不认为……无论如何,你应该把条件放在它之前,但在查询使用destroy_all,如下所示:

 Person.destroy_all("last_login < '2004-04-04'") Person.destroy_all(status: "inactive") Person.where(age: 0..18).destroy_all