1

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?

bjork24
  • 3,153
  • 7
  • 35
  • 46

3 Answers3

3

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.

Michaël Witrant
  • 7,525
  • 40
  • 44
1

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
sensae
  • 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
0

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?

Community
  • 1
  • 1
lorefnon
  • 12,875
  • 6
  • 61
  • 93