Josh Kuiros

Composing OR Queries in Rails 5.x

November 13, 2018

Rails 5 introduced the #or method to ActiveRecord::Relation. Combining ActiveRecord::Relation#or with lazy evaluation, you can compose dynamic OR queries that are pure ActiveRecord and protected from SQL injection:

bikes = [
  { kind: 'unicycle', color: 'blue' },
  { kind: 'road', color: 'white' },
  { kind: 'mountain', color: 'green' }
]
bikes.map do |bike|
  Bike.where(kind: bike.kind, color: bike.color)
end.reduce(&:or)

Produces an Active Record query like:
Bike
  .where(kind: 'unicycle', color: 'blue)
  .or(Bike.where(kind: 'road', color: 'white'))
  .or(Bike.where(kind: 'mountain', color: 'green'))

Produces 1 SQL query like:
SELECT *
FROM bikes
WHERE (kind = 'unicycle' AND color = 'blue')
OR (kind = 'road' AND color = 'white')
OR (kind = 'mountain' AND color = 'green');

Happy Coding 😊⚡️💻

I'm an Engineering Manager living and working in San Francisco. I'm passionate about building human-centered software and strong engineering cultures. Outside of code, you can find me cycling around the Bay Area.