Perform a Rails find() and iterate over the resulting records in groups
module ActiveRecord class Base # This method lets you iterate over the results of a .find, in groups. # (Basically an interface to LIMIT.) # Anything you can pass as options to .find, you can pass here. # Example 1: # Order.each_by(100, :conditions => { :cc_processed_at => nil }) do |order| # # do stuff with order # end # Example 2: # Person.each_by(50, :order => 'name') do |person, index| # # do stuff with person and index # end # Pass :update => true in the options to print a message before each group is # fetched from the db. # # Author: Elliot Winkler <elliot.winkler@gmail.com> # Source: http://snippets.dzone.com/posts/show/5461 def self.each_by(group_size, options={}, &blk) update = options.delete(:update) || false num_records = count(options.except(:from)) return 0 if num_records == 0 #raise "Number of records: #{num_records}" also_pass_offset = (blk.arity == 2) 0.step(num_records, group_size) do |offset| find_options = { :offset => offset, :limit => group_size }.merge(options) if update if num_records == 1 puts ">> Reading the only record." else start_offset = offset + 1 end_offset = offset + group_size end_offset = num_records if num_records < end_offset puts ">> Reading records #{start_offset}-#{end_offset}." end end find(:all, find_options).each do |record| also_pass_offset ? blk.call(record, offset) : blk.call(record) end end num_records end end end