Skip to content

Commit 4b6362e

Browse files
committed
Fix an incorrect autocorrect for Rails/Presence when a right-hand side of the relational operator
This PR fixes an incorrect autocorrect when there is right-hand side of the relational operator as follows: ```ruby a < if b.present? b else c end ``` Expect autocorrect ```ruby a < (b.presence || c) ``` Actual autocorrect ```ruby a < b.presence || c ```
1 parent d7db4d1 commit 4b6362e

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#816](https://github.com/rubocop/rubocop-rails/pull/816): Fix an incorrect autocorrect for `Rails/Presence` when a right-hand side of the relational operator. ([@ydah][])

lib/rubocop/cop/rails/presence.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def on_if(node)
9393

9494
def register_offense(node, receiver, other)
9595
add_offense(node, message: message(node, receiver, other)) do |corrector|
96-
corrector.replace(node.source_range, replacement(receiver, other))
96+
corrector.replace(node.source_range, replacement(receiver, other, node.left_sibling))
9797
end
9898
end
9999

@@ -106,7 +106,7 @@ def ignore_other_node?(node)
106106
end
107107

108108
def message(node, receiver, other)
109-
prefer = replacement(receiver, other).gsub(/^\s*|\n/, '')
109+
prefer = replacement(receiver, other, node.left_sibling).gsub(/^\s*|\n/, '')
110110
current = current(node).gsub(/^\s*|\n/, '')
111111
format(MSG, prefer: prefer, current: current)
112112
end
@@ -119,7 +119,7 @@ def current(node)
119119
end
120120
end
121121

122-
def replacement(receiver, other)
122+
def replacement(receiver, other, left_sibling)
123123
or_source = if other&.send_type?
124124
build_source_for_or_method(other)
125125
elsif other.nil? || other.nil_type?
@@ -128,7 +128,8 @@ def replacement(receiver, other)
128128
" || #{other.source}"
129129
end
130130

131-
"#{receiver.source}.presence" + or_source
131+
replaced = "#{receiver.source}.presence#{or_source}"
132+
left_sibling ? "(#{replaced})" : replaced
132133
end
133134

134135
def build_source_for_or_method(other)

spec/rubocop/cop/rails/presence_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,25 @@
301301
end
302302
end
303303

304+
context 'when a right-hand side of the relational operator' do
305+
%w[< > <= >= == !=].each do |operator|
306+
it "registers an offense and corrects when `#{operator}`" do
307+
expect_offense(<<~RUBY, operator: operator)
308+
a #{operator} if b.present?
309+
_{operator} ^^^^^^^^^^^^^ Use `(b.presence || c)` instead of `if b.present? ... end`.
310+
b
311+
else
312+
c
313+
end
314+
RUBY
315+
316+
expect_correction(<<~RUBY)
317+
a #{operator} (b.presence || c)
318+
RUBY
319+
end
320+
end
321+
end
322+
304323
it 'does not register an offense when using `#presence`' do
305324
expect_no_offenses(<<~RUBY)
306325
a.presence

0 commit comments

Comments
 (0)