Tapping ActiveRecord Relations
(Yes, I know I said I was probably not going to write here anymore, but while I like Medium for long-form articles, it didn’t quite fit the bill for posts that wanted syntax highlighting. Thus, I’ll probably continue to use the Buckblog for technical articles, and Medium for long-form.)
Not a lot of surprises in today’s post. I just wanted to share a convenient technique that I came across this week.
You’re all familiar with
Object#tap, right? It’s terribly useful, in many situations. The example from the documentation is pretty good:
You’re also probably all familiar with
ActiveRecord::Relation, at least indirectly. This is what is returned any time you query a model in ActiveRecord:
These relation objects allow query operations to be chained together (which you probably also already knew):
I’ve taken advantage of both
Object#tap and the chaining of
Relation instances, numerous times, but I don’t think I’ve ever done them together. Recently, though, I saw it done, something like this:
Here, the code collects the ids (
updated_ids) of all records that are affected by merging one author (
old_id) into another author (
#tap block just yields the relation, appends the ids of all matching records to the array, and then updates all matching records.
(Warning! This particular implementation has a race condition, and is not particularly efficient. A better way would be to use
RETURNING to fetch the updated ids, thus keeping the operation atomic, and efficient. This was just a novel application of ActiveRecord::Relation with
I love this about writing software. No matter how familiar you become with the toolbox you’ve been given, someone always manages to combine those tools in ways you wouldn’t have considered.