diff --git a/changelog/fix_false_positives_for_rails_presence_with_comparison_and_assignment_operators.md b/changelog/fix_false_positives_for_rails_presence_with_comparison_and_assignment_operators.md new file mode 100644 index 0000000000..1830b15169 --- /dev/null +++ b/changelog/fix_false_positives_for_rails_presence_with_comparison_and_assignment_operators.md @@ -0,0 +1 @@ +* [#1557](https://github.com/rubocop/rubocop-rails/issues/1557): Fix false positives for `Rails/Presence` with comparison and assignment operators. ([@davidenglishmusic][]) diff --git a/lib/rubocop/cop/rails/presence.rb b/lib/rubocop/cop/rails/presence.rb index e612eaf6ca..517f7c7a48 100644 --- a/lib/rubocop/cop/rails/presence.rb +++ b/lib/rubocop/cop/rails/presence.rb @@ -53,6 +53,16 @@ module Rails # # # good # a.presence&.foo + # + # # good + # a.present? ? a[1] : nil + # + # # good + # a[:key] = value if a.present? + # + # # good + # a.present? ? a > 1 : nil + # a <= 0 if a.present? class Presence < Base include RangeHelp extend AutoCorrector @@ -130,7 +140,7 @@ def ignore_other_node?(node) end def ignore_chain_node?(node) - node.method?('[]') || node.arithmetic_operation? + node.method?('[]') || node.method?('[]=') || node.arithmetic_operation? || node.comparison_method? end def message(node, replacement) diff --git a/spec/rubocop/cop/rails/presence_spec.rb b/spec/rubocop/cop/rails/presence_spec.rb index 433c8ca3b2..382978fb4d 100644 --- a/spec/rubocop/cop/rails/presence_spec.rb +++ b/spec/rubocop/cop/rails/presence_spec.rb @@ -295,12 +295,30 @@ RUBY end + it 'does not register an offense when chained method is `[]=`' do + expect_no_offenses(<<~RUBY) + a[1] = 1 if a.present? + RUBY + end + it 'does not register an offense when chained method is an arithmetic operation' do expect_no_offenses(<<~RUBY) a.present? ? a + 42 : nil RUBY end + it 'does not register an offense when using comparison operation in modifier if' do + expect_no_offenses(<<~RUBY) + a <= 0 if a.present? + RUBY + end + + it 'does not register an offense when chained method is a comparison operation in ternary' do + expect_no_offenses(<<~RUBY) + a.present? ? a > 42 : nil + RUBY + end + it 'does not register an offense when multiple methods are chained' do expect_no_offenses(<<~RUBY) a.present? ? a.foo.bar : nil