Skip to content

Commit 1f40f4b

Browse files
authored
Merge pull request rubocop#531 from koic/fix_a_false_positive_for_rails_lexically_scoped_action_filter
[Fix rubocop#529] Fix a false positive for `Rails/LexicallyScopedActionFilter`
2 parents 7e62ce2 + 03ed951 commit 1f40f4b

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
### Bug fixes
1212

1313
* [#528](https://github.com/rubocop/rubocop-rails/issues/528): Fix a false positive for `Rails/HasManyOrHasOneDependent` when specifying `:dependent` strategy with double splat. ([@koic][])
14+
* [#529](https://github.com/rubocop/rubocop-rails/issues/529): Fix a false positive for `Rails/LexicallyScopedActionFilter` when action method is aliased by `alias_method`. ([@koic][])
1415

1516
## Changes
1617

lib/rubocop/cop/rails/lexically_scoped_action_filter.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,10 @@ def on_send(node)
124124
block = parent.each_child_node(:begin).first
125125
return unless block
126126

127-
defined_methods = block.each_child_node(:def).map(&:method_name)
127+
defined_action_methods = defined_action_methods(block)
128+
128129
methods = array_values(methods_node).reject do |method|
129-
defined_methods.include?(method)
130+
defined_action_methods.include?(method)
130131
end
131132

132133
message = message(methods, parent)
@@ -135,6 +136,26 @@ def on_send(node)
135136

136137
private
137138

139+
def defined_action_methods(block)
140+
defined_methods = block.each_child_node(:def).map(&:method_name)
141+
142+
defined_methods + aliased_action_methods(block, defined_methods)
143+
end
144+
145+
def aliased_action_methods(node, defined_methods)
146+
alias_methods = node.each_child_node(:send).select { |send_node| send_node.method?(:alias_method) }
147+
148+
hash_of_alias_methods = alias_methods.each_with_object({}) do |alias_method, result|
149+
result[alias_method.last_argument.value] = alias_method.first_argument.value
150+
end
151+
152+
defined_methods.each_with_object([]) do |defined_method, aliased_method|
153+
if (new_method_name = hash_of_alias_methods[defined_method])
154+
aliased_method << new_method_name
155+
end
156+
end
157+
end
158+
138159
# @param node [RuboCop::AST::Node]
139160
# @return [Array<Symbol>]
140161
def array_values(node) # rubocop:disable Metrics/MethodLength

spec/rubocop/cop/rails/lexically_scoped_action_filter_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,41 @@ def logout
115115
RUBY
116116
end
117117

118+
it 'does not register an offense when action method is aliased by `alias_method`' do
119+
expect_no_offenses(<<~RUBY)
120+
class FooController < ApplicationController
121+
before_action :authorize!, only: %i[index show]
122+
123+
def index
124+
end
125+
alias_method :show, :index
126+
127+
private
128+
129+
def authorize!
130+
end
131+
end
132+
RUBY
133+
end
134+
135+
it 'registers an offense when action method is not aliased by `alias_method`' do
136+
expect_offense(<<~RUBY)
137+
class FooController < ApplicationController
138+
before_action :authorize!, only: %i[foo show]
139+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` is not explicitly defined on the class.
140+
141+
def index
142+
end
143+
alias_method :show, :index
144+
145+
private
146+
147+
def authorize!
148+
end
149+
end
150+
RUBY
151+
end
152+
118153
it "doesn't register an offense when using conditional statements" do
119154
expect_no_offenses <<~RUBY
120155
class Test < ActionController

0 commit comments

Comments
 (0)