30

I can use Rails find_each method like :

User.find_each(:batch_size => 10000) do |user| ------ end 

With find_each method is there any way to get the index of the array ? like :

User.find_each(:batch_size => 10000).with_index do |user, index| ------ end 
0

5 Answers 5

81

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 
Sign up to request clarification or add additional context in comments.

1 Comment

Note: batch_size defaults to 1000 so if that suits your needs you can just use User.find_each.with_index. api.rubyonrails.org/v4.2.5/classes/ActiveRecord/…
27

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.

4 Comments

yes I got it.. A small modification in the user model code: def self.find_each(options = {}) find_in_batches(options) do |records| records.each_with_index { |record, index| yield record, index } end end Now its working.. Thanks...
I have written find_each_with_index method. But this find_each_with_index method is repeating the index after each batch sizes!! No use of the index now. So I used a variable to get the indexes with find_each method.
Take a look to Ron answer if you're using rails 4
@Naremy when I asked this qn, this functionality was not implemented in any Rails versions. Now it has. thx
12

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.

1 Comment

Thanks...Martin.. This is the another solution for my Qn. And glad that Rails is including this method! Nice!
1

Just use an local variable:

index = 0 User.find_each(:batch_size => 10000) do |user| ------ index += 1 end 

Comments

-6

You can get all users and send them through a block along with their corresponding index as follows.

User.all.each_with_index do |user, index| puts "email is " + "#{user.email}" + " and user index is " + "#{index}" end 

1 Comment

The Main reason I am using the find_each instead of the .all is to reduce the mysql load. Because I have a huge user data.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.