Welcome to another insightful installment of TWIL; your weekly micro-lesson in complex software development! This week, Katie enhances our ActiveRecord arsenal by introducing New Ranges for LT/GT in ActiveRecord Queries. Discover how Ruby and Rails' evolving syntax simplifies database search criteria far beyond simple equalities, allowing for elegant and error-resistant range-based queries. Dive into Katie's latest guide to learn how ActiveRecord has shed cumbersome raw SQL for the sophistication of endless ranges, streamlining the quest for records by attributes greater or lesser than a dynamic value, all within the elegant embrace of Ruby's syntactic sugar.
New ranges for LT/GT in ActiveRecord Queries
Problem?
Using the ActiveRecord query interface, retrieving objects where some property is equal to a given value looks like this:
User.where(active: true)
This will return user records that have an active
value of true
.
This can be used for retrieving records where the property matches a set of values as well:
User.where(favorite_animal: ['cat', 'dog'])
This will return user records that have a favorite_animal
value of either cat
or dog
.
For greater than/less than queries, though, previous versions of Ruby/Rails unfortunately required writing a little bit of SQL:
User.where('users.id > ?', 10)
This would return user records with an id
greater than 10.
User.where('users.last_logged_in_at < ?', 1.day.ago)
This would return user records with a last_logged_in_at
timestamp earlier than one day ago.
This is a little bit gross, prone to human error (or, at the very least, inconsistency), and not very Rails-y.
Solution!
As of Ruby 2.6, we can use endless ranges (and beginless ranges as of Ruby 2.7).
1..10
1...10
To rewrite the above greater than/less than queries using the newly-introduced open ranges:
User.where(id: 10...)
This would return user records with an id
greater than 10.
User.where(last_logged_in_at: ...1.day.ago)
This would return user records with a last_logged_in_at
timestamp earlier than one day ago.
Note:
For inclusive ranges (i.e., <=
/ >=
queries), the syntax is ..
instead of exclusive ranges' ...
Resources
- Ruby
- Rails