Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Duncan Beevers http://duncan.beevers.net

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

ActiveRecord each_by_page

Perform an operation on a set of models including ActiveRecord callbacks, without instantiating all models at once.

Step through and instantiate each member of the class and execute on it, but instantiate no more than per_page instances at any given time.
Safe for destructive actions or actions that modify the fields your :order or :conditions clauses operate on.

   1  
   2  module ActiveRecord
   3    class Base
   4      def each_by_page per_page, options = {}, &block
   5        # By-id for model-modifying blocks
   6        # Build SQL to get ids of all matching records using the options provided by the user
   7        sql = construct_finder_sql(options.dup.merge({ :select => 'id' }))
   8        # Get the results as an array of tiny hashes { "id" => "1" } and flatten them out to just the ids
   9        all_ids = connection.select_all(sql).map { |h| h['id'] }
  10        at_a_time = 0..(per_page-1)
  11   
  12        # chop apart the all_ids array a segment at a time
  13        begin
  14          ids = all_ids.slice!(at_a_time)
  15          ids_cases = []
  16          ids.each_with_index { |id, i| ids_cases << "WHEN #{id} THEN #{i}" }
  17          ids_cases = ids_cases.join(' ')
  18   
  19          # Do the deed on this page of results
  20          find(:all, options.merge(
  21            :conditions => [ 'id IN (?)', ids ],
  22            :order => "CASE id #{ids_cases} END"
  23          )).each &block
  24   
  25        end until all_ids.empty?
  26      end
  27    end
  28  end


link to blog entry
« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS