I have a table that I'd like to keep pruned to the 500 most recent rows. What's the most efficient way to do this in rails?
3 Answers
One way to do it:
class MyModel
after_create do
self.class.prune(500)
end
def self.prune(max)
if count > max
order('created_at DESC').offset(max).each do |model|
model.destroy
end
end
end
end
The prune
class method could also be added to ActiveRecord::Base
if you want to use that on multiple models.

- 7,525
- 40
- 44
This is definitely one way to do it, although someone may chime in with a more efficient way. Create a method in your controller, for this example I'll call it "prune", and call it after your create action (there may be an after_filter or something similar you can use.) It should look something like this.
def prune
if MyModel.count > 500
@models = MyModel.all(:offset => 500)
@models.each do |m|
m.destroy!
end
end
end

- 493
- 3
- 12
-
This will remove the most recent rows, not the oldest ones (although [this is not guaranteed](http://forums.mysql.com/read.php?21,239471,239688#msg-239688) because there's no explicit order). – Michaël Witrant Jul 19 '11 at 07:06
-
Oh my, I forgot to order my results. – sensae Jul 21 '11 at 07:06
A basic solution would be to use the following script under a scheduling application like whenever https://github.com/javan/whenever to run the following command :
Mould.order('updated_at DESC').offset(20).each {|m| m.destroy }
Substitute Mould with the name of your model. Usage of cron and scheduling has been discussed in detail in following post : A cron job for rails: best practices?