From 3ed815332086b73b9ae6db0daaf26a4f40a58d74 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Thu, 24 Jun 2021 14:05:33 +1000 Subject: [PATCH] Fix Rails/FindBy when calling Range#first or #take - Minimal working example - Fix failing spec - Extract #where_method? - Add spec for Range#first --- CHANGELOG.md | 2 ++ lib/rubocop/cop/rails/find_by.rb | 9 +++++++-- spec/rubocop/cop/rails/find_by_spec.rb | 12 ++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd73a7561..a981910f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug fixes * [#509](https://github.com/rubocop/rubocop-rails/pull/509): Fix an error for `Rails/ReflectionClassName` when using `class_name: to_s`. ([@skryukov][]) +* [#510](https://github.com/rubocop/rubocop-rails/pull/510): Fix an error for `Rails/FindBy` when calling `#first` or `#take` on a `Range` object. ([@johnsyweb][]) * [#507](https://github.com/rubocop/rubocop-rails/pull/507): Fix an error for `Rails/FindBy` when calling `take` after block. ([@koic][]) * [#504](https://github.com/rubocop/rubocop-rails/issues/504): Fix a false positive for `Rails/FindBy` when receiver is not an Active Record. ([@nvasilevski][]) @@ -413,3 +414,4 @@ [@aesthetikx]: https://github.com/aesthetikx [@nvasilevski]: https://github.com/nvasilevski [@skryukov]: https://github.com/skryukov +[@johnsyweb]: https://github.com/johnsyweb diff --git a/lib/rubocop/cop/rails/find_by.rb b/lib/rubocop/cop/rails/find_by.rb index 037471b7ff..69d5925211 100644 --- a/lib/rubocop/cop/rails/find_by.rb +++ b/lib/rubocop/cop/rails/find_by.rb @@ -32,8 +32,7 @@ class FindBy < Base RESTRICT_ON_SEND = %i[first take].freeze def on_send(node) - receiver = node.receiver - return unless receiver&.method?(:where) + return unless where_method?(node.receiver) return if ignore_where_first? && node.method?(:first) range = range_between(node.receiver.loc.selector.begin_pos, node.loc.selector.end_pos) @@ -46,6 +45,12 @@ def on_send(node) private + def where_method?(receiver) + return false unless receiver + + receiver.respond_to?(:method?) && receiver.method?(:where) + end + def autocorrect(corrector, node) return if node.method?(:first) diff --git a/spec/rubocop/cop/rails/find_by_spec.rb b/spec/rubocop/cop/rails/find_by_spec.rb index 8aa6b5a4d8..0a4ef8890e 100644 --- a/spec/rubocop/cop/rails/find_by_spec.rb +++ b/spec/rubocop/cop/rails/find_by_spec.rb @@ -92,5 +92,17 @@ RUBY end end + + context 'when method is Range#first' do + it 'does not register an offense' do + expect_no_offenses('(1..2).first') + end + end + + context 'when method is Range#take' do + it 'does not register an offense' do + expect_no_offenses('(1..2).take(1)') + end + end end end