Doing stuff with Rails’ find_each

Jon Abrams
Sep 17, 2016 · 2 min read

If you’ve been making web apps with Rails for long enough, you will have encountered ActiveRecord’s handy find_each method. It iterates over a bunch of records, loading only 1000 at a time, which allows you to avoid running out of memory. Pretty handy if you need to do something to all 1 million of your User records!

When you use find_each, you probably just pass it a block like so:

That’s well and good if you want to do something to each user. But what if you need to find that one particular user out of a million that fails validation? That’s not something the DB can easily query.

Did you know that find_each can be called without a block? If you do that, it instead return an enumerable, which then allows you to call any of the typical Ruby array methods you’re used to. For example, if you want to find all invalid users:

Depending on your situation, that may return way too many users. What if you just want the earliest invalid user?

Hold on, isn’t find used for looking up records by their primary key? Not in this case. Since find_each returns an Enumerable (not an ActiveRecord Class), this is Ruby’s find, not ActiveRecord’s find. It iterates over each object passed to it and return the first to result in true from the block.

You can use any of the Enumerable methods, including any?, reduce, or count. I recommend avoiding methods like map and sort since you end up loading all the records into memory, which is probably what you wanted to avoid by using find_each.

Bonus: When using find_each you can first filter out records using where, but you cannot order them using order, nor can you use limit. Those will just silently not work! As always, read the documentation… carefully.

Jon Abrams

Written by

Canadian Software Engineer in California

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade