rubocop-rails
rubocop-rails copied to clipboard
Cop idea: Rails/WhereBetween
Problem
User.where("created_at > ?", 30.days.ago).where("created_at < ?", 7.days.ago)
Describe the solution you'd like
Add a cop that would suggest using ranges instead:
User.where(created_at: 7.days.ago..30.days.ago)
Describe alternatives you've considered
Nothing specifically. Personally, I often choose to use ranges even when the constraint is just on one side of the range:
- User.where("created_at > ?", 30.days.ago)
+ User.where(created_at: 30.days.ago..)
Additional context
This is used in the wild, see e.g.
# gitlabhq/app/models/release.rb
scope :released_within_2hrs, -> { where(released_at: Time.zone.now - 1.hour..Time.zone.now + 1.hour) }
could be safely simplified to:
scope :released_within_2hrs, -> { where(released_at: 1.hour.ago..1.hour.from_now) }
Looks good to me. I don't remember the version clearly, but there would have been minimum Rails versions that supported begginless and endless ranges respectively. Anyway it would be better to be shown in the Rails Style Guide first :-)
It seems to be supported since Rails 4.0.0.
FYI, Rails 6.0 or later is required for endless range in Ruby 2.6 syntax and beginless range in Ruby 2.7 syntax:
- Support endless ranges in where ... https://github.com/rails/rails/pull/34906
- Beginless range in where condition ... https://github.com/rails/rails/issues/38777
So, non-abbreviation range syntax is fine, but these abbreviation syntax will need to be noted.
For anyone interested, implemented a PR to address this.