Module: BetterRecord::Relation
- Defined in:
- lib/better_record/relation.rb
Instance Method Summary collapse
-
#pluck_in_batches(*columns, batch_size: 1000) ⇒ Object
pluck_in_batches: yields an array of *columns that is at least size batch_size to a block.
Instance Method Details
#pluck_in_batches(*columns, batch_size: 1000) ⇒ Object
pluck_in_batches: yields an array of *columns that is at least size
batch_size to a block.
Special case: if there is only one column selected than each batch
will yield an array of columns like [:column, :column, ...]
rather than [[:column], [:column], ...]
Arguments
columns -> an arbitrary selection of columns found on the table.
batch_size -> How many items to pluck at a time
&block -> A block that processes an array of returned columns.
Array is, at most, size batch_size
Returns
nothing is returned from the function
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/better_record/relation.rb', line 19 def pluck_in_batches(*columns, batch_size: 1000) if columns.empty? raise "There must be at least one column to pluck" end # the :id to start the query at batch_start = nil # It's cool. We're only taking in symbols # no deep clone needed select_columns = columns.dup # Find index of :id in the array remove_id_from_results = false id_index = columns.index(primary_key.to_sym) # :id is still needed to calculate offsets # add it to the front of the array and remove it when yielding if id_index.nil? id_index = 0 select_columns.unshift(primary_key) remove_id_from_results = true end loop do relation = self.reorder(table[primary_key].asc).limit(batch_size) relation = relation.where(table[primary_key].gt(batch_start)) if batch_start items = relation.pluck(*select_columns) break if items.empty? # Use the last id to calculate where to offset queries last_item = items.last batch_start = last_item.is_a?(Array) ? last_item[id_index] : last_item # Remove :id column if not in *columns items.map! { |row| row[1..-1] } if remove_id_from_results yield items break if items.size < batch_size end end |