From 853b1eb8af29b209ad7a7c955a605df6d70fcf5a Mon Sep 17 00:00:00 2001 From: Benjamin Quorning Date: Tue, 19 Dec 2023 17:35:45 +0100 Subject: [PATCH] [Fix #1221] Fix bug in Rails/WhereNot Fix `Rails/WhereNot` which raised an exception when calling `.where` on an implicit receiver (e.g. inside model code). --- changelog/fix_where_not_with_implicit_receiver.md | 1 + lib/rubocop/cop/rails/where_not.rb | 3 ++- spec/rubocop/cop/rails/where_not_spec.rb | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_where_not_with_implicit_receiver.md diff --git a/changelog/fix_where_not_with_implicit_receiver.md b/changelog/fix_where_not_with_implicit_receiver.md new file mode 100644 index 0000000000..d820b61190 --- /dev/null +++ b/changelog/fix_where_not_with_implicit_receiver.md @@ -0,0 +1 @@ +* [#1221](https://github.com/rubocop/rubocop-rails/issues/1221): Fix an exception in `Rails/WhereNot` when calling `.where` on an implicit receiver (e.g. inside model code). ([@bquorning][]) diff --git a/lib/rubocop/cop/rails/where_not.rb b/lib/rubocop/cop/rails/where_not.rb index fd6ad6d65e..742fc56073 100644 --- a/lib/rubocop/cop/rails/where_not.rb +++ b/lib/rubocop/cop/rails/where_not.rb @@ -46,7 +46,7 @@ def on_send(node) column_and_value = extract_column_and_value(template_node, value_node) return unless column_and_value - good_method = build_good_method(node.loc.dot.source, *column_and_value) + good_method = build_good_method(node.loc.dot&.source, *column_and_value) message = format(MSG, good_method: good_method) add_offense(range, message: message) do |corrector| @@ -88,6 +88,7 @@ def extract_column_and_value(template_node, value_node) end def build_good_method(dot, column, value) + dot ||= '.' if column.include?('.') table, column = column.split('.') diff --git a/spec/rubocop/cop/rails/where_not_spec.rb b/spec/rubocop/cop/rails/where_not_spec.rb index aa257d7246..d0dfd4ce2a 100644 --- a/spec/rubocop/cop/rails/where_not_spec.rb +++ b/spec/rubocop/cop/rails/where_not_spec.rb @@ -111,6 +111,17 @@ RUBY end + it 'registers an offense and corrects when using implicit receiver' do + expect_offense(<<~RUBY) + where('name != ?', 'Gabe') + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `where.not(name: 'Gabe')` instead of manually constructing negated SQL in `where`. + RUBY + + expect_correction(<<~RUBY) + where.not(name: 'Gabe') + RUBY + end + context 'with array arguments' do it 'registers an offense and corrects when using `!=` and anonymous placeholder' do expect_offense(<<~RUBY)