Skip to content

Instantly share code, notes, and snippets.

@agibralter
Created January 3, 2009 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agibralter/42798 to your computer and use it in GitHub Desktop.
Save agibralter/42798 to your computer and use it in GitHub Desktop.
module ActiveRecordEachBy
# 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 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
ActiveRecord::Base.extend(ActiveRecordEachBy)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment