Created
January 3, 2009 05:30
-
-
Save agibralter/42798 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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