#Destroyer

Deletes records(without instantiating the records first) based on a block(which returns an array of ids) given and also recursively deletes all their associated records if they are marked as :dependent => :destroy. It is useful for background processing.

Installing

Add this to your Gemfile

gem 'destroyer'

##How to use it

Add destroyer with a lambda or Proc to the model you want to delete records from which returns an array of ids, like this:

class User < ActiveRecord::Base
  destroyer lambda { select("id").where(['created_at < ?', Time.now])] }
end

Then, whenever you want to delete the records just call start_destroyer on your model, like this:

User.start_destroyer

You could also send a new block to destroyer method:

User.destroyer( lambda { User.select('id').where('rol_id = 4') })

And then, just call start_destroyer on the model and it will execute the process with the block that you just passed to destroyer method, keep in mind that the original block will not be overwritten, but be sure to execute start_destroyer whenever you pass a new block, otherwise this block will be present(because Destroyer uses class instance variables) the next time you call start_destroyer and it will try to delete the records with the ids given in the block, or make sure to set destroyer_block to nil on the model, like this:

User.destroyer_block = nil

##Notes

destroyer also accepts a hash of options, the only available option is batch_size, it is used to delete all records in batches, by default is 1000, make sure to set it to and empty hash if you modified the value and did not call start_destroyer, otherwise it will have the last value the next time you call the start_destroyer method.

If you do not specify a default block, and later in the code you call your Model.destroyer with a block, that block will become the default block.

##Example

class PurchaseOrder < ActiveRecord::Base
  has_many :line_items, :dependent => :destroy
  destroyer lambda { select("id").where(["state = 'deleted' AND created_at < ?", 1.month.ago]) }
end

class LineItem < ActiveRecord::Base
  has_many :variant_line_items, :dependent => :destroy
  belongs_to :purchase_order
end

class VariantLineItem < ActiveRecord::Base
  belongs_to :line_item
end

PurchaseOrder.start_destroyer

And that code is going to delete all purchase orders which 'state' is 'deleted' and are older that one month ago, and it will also delete all its related line items as well as all their variant line items.

About the Author

Crowd Interactive is a web design and development company that happens to work in Colima, Mexico. We specialize in building and growing online retail stores. We don’t work with everyone – just companies we believe in. Call us today to see if there’s a fit. Find more info here!