Skip to content

Commit 1980681

Browse files
committed
[Fix #1427] Fix an error for Rails/UniqBeforePluck with multi-line expression
This introduces a bit of whitespace when the expression spans multiple lines, but that seesm fine
1 parent 159045f commit 1980681

File tree

3 files changed

+31
-33
lines changed

3 files changed

+31
-33
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#1427](https://github.com/rubocop/rubocop-rails/issues/1427): Fix an error for `Rails/UniqBeforePluck` when `pluck` and `unique` are on different lines. ([@earlopain][])

lib/rubocop/cop/rails/uniq_before_pluck.rb

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,51 +51,28 @@ class UniqBeforePluck < Base
5151

5252
MSG = 'Use `distinct` before `pluck`.'
5353
RESTRICT_ON_SEND = %i[uniq].freeze
54-
NEWLINE = "\n"
55-
PATTERN = '[!^block (send (send %<type>s :pluck ...) :uniq ...)]'
5654

57-
def_node_matcher :conservative_node_match, format(PATTERN, type: 'const')
58-
59-
def_node_matcher :aggressive_node_match, format(PATTERN, type: '_')
55+
def_node_matcher :uniq_before_pluck, '[!^block $(send $(send _ :pluck ...) :uniq ...)]'
6056

6157
def on_send(node)
62-
uniq = if style == :conservative
63-
conservative_node_match(node)
64-
else
65-
aggressive_node_match(node)
66-
end
67-
68-
return unless uniq
58+
uniq_before_pluck(node) do |uniq_node, pluck_node|
59+
next if style == :conservative && !pluck_node.receiver&.const_type?
6960

70-
add_offense(node.loc.selector) do |corrector|
71-
autocorrect(corrector, node)
61+
add_offense(uniq_node.loc.selector) do |corrector|
62+
autocorrect(corrector, uniq_node, pluck_node)
63+
end
7264
end
7365
end
7466

7567
private
7668

77-
def autocorrect(corrector, node)
78-
method = node.method_name
69+
def autocorrect(corrector, uniq_node, pluck_node)
70+
corrector.remove(range_between(pluck_node.loc.end.end_pos, uniq_node.loc.selector.end_pos))
7971

80-
corrector.remove(dot_method_with_whitespace(method, node))
81-
if (dot = node.receiver.loc.dot)
72+
if (dot = pluck_node.loc.dot)
8273
corrector.insert_before(dot.begin, '.distinct')
8374
else
84-
corrector.insert_before(node.receiver, 'distinct.')
85-
end
86-
end
87-
88-
def dot_method_with_whitespace(method, node)
89-
range_between(dot_method_begin_pos(method, node), node.loc.selector.end_pos)
90-
end
91-
92-
def dot_method_begin_pos(method, node)
93-
lines = node.source.split(NEWLINE)
94-
95-
if lines.last.strip == ".#{method}"
96-
node.source.rindex(NEWLINE)
97-
else
98-
node.loc.dot.begin_pos
75+
corrector.insert_before(pluck_node, 'distinct.')
9976
end
10077
end
10178
end

spec/rubocop/cop/rails/uniq_before_pluck_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@
3737
RUBY
3838
end
3939

40+
it 'corrects when uniq and pluck are on different lines' do
41+
expect_offense(<<~RUBY)
42+
Model
43+
.pluck(:name)
44+
.uniq
45+
^^^^ Use `distinct` before `pluck`.
46+
RUBY
47+
48+
expect_correction(<<~RUBY)
49+
Model
50+
.distinct.pluck(:name)
51+
RUBY
52+
end
53+
4054
it 'ignores uniq before pluck' do
4155
expect_no_offenses(<<~RUBY)
4256
Model.where(foo: 1).uniq.pluck(:something)
@@ -85,6 +99,12 @@
8599
instance.assoc.pluck(:name).uniq
86100
RUBY
87101
end
102+
103+
it 'ignores uniq without an receiver' do
104+
expect_no_offenses(<<~RUBY)
105+
pluck(:name).uniq
106+
RUBY
107+
end
88108
end
89109

90110
context 'when the enforced mode is aggressive' do

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy