coderz coderz - 6 months ago 17
Ruby Question

In Rails, what's the difference between find_each and where?

In Rails, both find_each and where are used for retrieving data from Database supported by ActiveRecord.

You can pass your query condition to

where
, like:

c = Category.where(:name => 'Ruby', :position => 1)


And you can pass batch size to
find_each
, like:

Hedgehog.find_each(batch_size: 50).map{ |p| p.to_json }


But what's the difference between the following 2 code?

# code 1
Person.where("age > 21").find_each(batch_size: 50) do |person|
# processing
end

# code 2
Person.where("age > 21").each do |person|
# processing
end


Does code 1 batch retrieve 50 tuples each time, and code 2 retrieve all tuples in one time? More details explaination is welcomed.

My opinion is:


  1. both
    where
    and
    find_each
    can be used for batch retrieving, but user can define batch size when using
    find_each
    .

  2. find_each
    does not support passing query condition.



Please correct me if my understanding is wrong.

Answer

An active record relation does not automatically load all records into memory.

When you call #each, all records will be loaded into memory. When you call #find_each, records will be loaded into memory in batches of the given batch size.

So when your query returns a number of records that would be too much memory for the server's available resources, then using #find_each would be a great choice.

It's basically like using ruby's lazy enumeration #to_enum#lazy with #each_slice and then #each (very convenient).