diff --git a/changelog/fix_a_false_positive_for_rails_redundant_active_record_all_method.md b/changelog/fix_a_false_positive_for_rails_redundant_active_record_all_method.md new file mode 100644 index 0000000000..b722244ff4 --- /dev/null +++ b/changelog/fix_a_false_positive_for_rails_redundant_active_record_all_method.md @@ -0,0 +1 @@ +* [#1126](https://github.com/rubocop/rubocop-rails/pull/1126): Fix a false positive for `Rails/RedundantActiveRecordAllMethod` when using some `Enumerable`'s methods with block argument. ([@koic][]) diff --git a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb index 9349179de3..ee4d010bd8 100644 --- a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +++ b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb @@ -127,12 +127,15 @@ class RedundantActiveRecordAllMethod < Base without ].to_set.freeze + POSSIBLE_ENUMERABLE_BLOCK_METHODS = %i[any? find select].freeze + def_node_matcher :followed_by_query_method?, <<~PATTERN (send (send _ :all) QUERYING_METHODS ...) PATTERN def on_send(node) return unless followed_by_query_method?(node.parent) + return if possible_enumerable_block_method?(node) return if node.receiver.nil? && !inherit_active_record_base?(node) range_of_all_method = offense_range(node) @@ -144,6 +147,13 @@ def on_send(node) private + def possible_enumerable_block_method?(node) + parent = node.parent + return false unless POSSIBLE_ENUMERABLE_BLOCK_METHODS.include?(parent.method_name) + + parent.parent&.block_type? || parent.parent&.numblock_type? || parent.first_argument&.block_pass_type? + end + def offense_range(node) range_between(node.loc.selector.begin_pos, node.source_range.end_pos) end diff --git a/spec/rubocop/cop/rails/redundant_active_record_all_method_spec.rb b/spec/rubocop/cop/rails/redundant_active_record_all_method_spec.rb index 888f734b69..d0c42d3586 100644 --- a/spec/rubocop/cop/rails/redundant_active_record_all_method_spec.rb +++ b/spec/rubocop/cop/rails/redundant_active_record_all_method_spec.rb @@ -387,5 +387,65 @@ class User < ::ActiveRecord::Base end RUBY end + + context 'using `any?`' do + it 'does not register an offense when using `any?` with block' do + expect_no_offenses(<<~RUBY) + User.all.any? { |item| item.do_something } + RUBY + end + + it 'does not register an offense when using `any?` with numbered block' do + expect_no_offenses(<<~RUBY) + User.all.any? { _1.do_something } + RUBY + end + + it 'does not register an offense when using `any?` with symbol block' do + expect_no_offenses(<<~RUBY) + User.all.any?(&:do_something) + RUBY + end + end + + context 'using `find`' do + it 'does not register an offense when using `find` with block' do + expect_no_offenses(<<~RUBY) + User.all.find { |item| item.do_something } + RUBY + end + + it 'does not register an offense when using `find` with numbered block' do + expect_no_offenses(<<~RUBY) + User.all.find { _1.do_something } + RUBY + end + + it 'does not register an offense when using `find` with symbol block' do + expect_no_offenses(<<~RUBY) + User.all.find(&:do_something) + RUBY + end + end + + context 'using `select`' do + it 'does not register an offense when using `select` with block' do + expect_no_offenses(<<~RUBY) + User.all.select { |item| item.do_something } + RUBY + end + + it 'does not register an offense when using `select` with numbered block' do + expect_no_offenses(<<~RUBY) + User.all.select { _1.do_something } + RUBY + end + + it 'does not register an offense when using `select` with symbol block' do + expect_no_offenses(<<~RUBY) + User.all.select(&:do_something) + RUBY + end + end end end