rubocop-rails icon indicating copy to clipboard operation
rubocop-rails copied to clipboard

Cop idea: Rails/WhereBetween

Open pirj opened this issue 2 years ago • 3 comments

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) }

pirj avatar Apr 07 '22 21:04 pirj

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 :-)

koic avatar May 02 '22 03:05 koic

It seems to be supported since Rails 4.0.0.

pirj avatar May 02 '22 11:05 pirj

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.

koic avatar May 03 '22 03:05 koic

For anyone interested, implemented a PR to address this.

fatkodima avatar Apr 26 '24 12:04 fatkodima