Skip to content

Commit 72feeb5

Browse files
authored
Merge pull request #619 from nvasilevski/fix-read-write-attribute-cop
[Fix #623] Skip method shadowing check if attr is not sym or str for ReadWriteAttribute
2 parents ba2a7e3 + 0d2c43c commit 72feeb5

File tree

3 files changed

+81
-5
lines changed

3 files changed

+81
-5
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#623](https://github.com/rubocop/rubocop-rails/issues/623): Fix method shadowing check for `Rails/ReadWriteAttribute` cop. ([@nvasilevski][])

lib/rubocop/cop/rails/read_write_attribute.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,15 @@ def on_send(node)
5959
private
6060

6161
def within_shadowing_method?(node)
62-
node.each_ancestor(:def).any? do |enclosing_method|
63-
shadowing_method_name = node.first_argument.value.to_s
64-
shadowing_method_name << '=' if node.method?(:write_attribute)
62+
first_arg = node.first_argument
63+
return false unless first_arg.respond_to?(:value)
6564

66-
enclosing_method.method_name.to_s == shadowing_method_name
67-
end
65+
enclosing_method = node.each_ancestor(:def).first
66+
return false unless enclosing_method
67+
68+
shadowing_method_name = first_arg.value.to_s
69+
shadowing_method_name << '=' if node.method?(:write_attribute)
70+
enclosing_method.method?(shadowing_method_name)
6871
end
6972

7073
def build_message(node)

spec/rubocop/cop/rails/read_write_attribute_spec.rb

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,42 @@ def foo
8989
it 'registers no offense with explicit receiver' do
9090
expect_no_offenses('res = object.read_attribute(:test)')
9191
end
92+
93+
context 'when used within a method' do
94+
context 'when using variable for the attribute name' do
95+
it 'registers an offense and corrects' do
96+
expect_offense(<<~RUBY)
97+
def do_the_read_from(column)
98+
read_attribute(column)
99+
^^^^^^^^^^^^^^^^^^^^^^ Prefer `self[column]`.
100+
end
101+
RUBY
102+
103+
expect_correction(<<~RUBY)
104+
def do_the_read_from(column)
105+
self[column]
106+
end
107+
RUBY
108+
end
109+
end
110+
111+
context 'when using constant for the attribute name' do
112+
it 'registers an offense and corrects' do
113+
expect_offense(<<~RUBY)
114+
def do_the_read
115+
read_attribute(ATTR_NAME)
116+
^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `self[ATTR_NAME]`.
117+
end
118+
RUBY
119+
120+
expect_correction(<<~RUBY)
121+
def do_the_read
122+
self[ATTR_NAME]
123+
end
124+
RUBY
125+
end
126+
end
127+
end
92128
end
93129

94130
context 'write_attribute' do
@@ -105,6 +141,42 @@ def foo
105141
end
106142
end
107143

144+
context 'when used within a method' do
145+
context 'when using variable for the attribute name' do
146+
it 'registers an offense and corrects' do
147+
expect_offense(<<~RUBY)
148+
def do_the_write_to(column)
149+
write_attribute(column, 'value')
150+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `self[column] = 'value'`.
151+
end
152+
RUBY
153+
154+
expect_correction(<<~RUBY)
155+
def do_the_write_to(column)
156+
self[column] = 'value'
157+
end
158+
RUBY
159+
end
160+
end
161+
162+
context 'when using constant for the attribute name' do
163+
it 'registers an offense and corrects' do
164+
expect_offense(<<~RUBY)
165+
def do_the_write(value)
166+
write_attribute(ATTR_NAME, value)
167+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `self[ATTR_NAME] = value`.
168+
end
169+
RUBY
170+
171+
expect_correction(<<~RUBY)
172+
def do_the_write(value)
173+
self[ATTR_NAME] = value
174+
end
175+
RUBY
176+
end
177+
end
178+
end
179+
108180
context 'when using a string for the attribute' do
109181
it 'registers an offense and corrects' do
110182
expect_offense(<<~RUBY)

0 commit comments

Comments
 (0)