ActiveRecord — Named Query Fragment Placeholders
Whenever I wanted to use placeholders in raw SQL query fragments in Rails, I would use ?
and end up writing —
Post.where('published_at > ?', some_time)
What if I wanted to add another condition that checks against the same value in some_time
?
Post.where('published_at > ? OR saved_at > ?', some_time, some_time)
To be perfectly honest, writing such code never bothered me and I did not put in the little effort that was needed to see if there was a better way to do this.
One day I was pairing with one of my colleagues, Preethi Kumar, and she had something that looked like symbols in her query fragments, like this — published_at > :date
.
I had seen nothing like that before and I was wondering if that was some esoteric database feature or something :D
That’s when I got to know that you can use named placeholders in query fragments and pass in a hash for ActiveRecord to resolve those values.
And now, I can happily re-write my statement as —
Post.where('published_at > :time OR saved_at > :time', selected_time: some_time)
Easily one can see many small wins with this like —
- Longer queries become more readable, provided the placeholder names are well thought out. Reduces cognitive overhead.
- You’re not repeatedly writing out variables that are used multiple times.
- Positional coupling is broken.