In Rails how do I use find_each method with index?
Your question is already implemented in the Rails master branch. To get this, it requires using Rails edge, as this has not been merged into any release as of yet. See this merged pull request: https://github.com/rails/rails/pull/10992.
So add this to your Gemfile:
gem 'rails', github: 'rails/rails'
This will allow you to run the code you described:
User.find_each(batch_size: 10000).with_index do |user, index|
puts "UserID: #{user.id.to_s} has index ##{index.to_s}"
end
Granted, running on the edge release is risky, so don't do this in production. But look at the pull request to see the small amount of code added to get this working. You can monkey patch until it is merged into a Rails release.
Update: As of Rails 4.1.4 this is possible. See this answer for more. Example:
User.find_each(:batch_size => 1000).with_index do |user, index|
user.call_method(index)
end
As you can see from the method definition, this is not possible.
def find_each(options = {})
find_in_batches(options) do |records|
records.each { |record| yield record }
end
end
In order to accomplish what you want to do, you need to either create your own modified version of the method
class User
def find_each(options = {})
find_in_batches(options) do |records|
records.each_with_index { |record| yield record, index }
end
end
end
User.find_each(:batch_size => 10000) do |user, index|
------
end
or use an instance variable.
index = 0
User.find_each(:batch_size => 10000) do |user|
# ...
index += 1
end
There is no other default solution as shown by the method implementation.
As an update to this question. Active Record 4.1.4 has added support for find_each.with_index
as pointed in the documentation.
User.find_each(:batch_size => 1000).with_index do |user, index|
user.call_method(index)
end