New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new Rails/LexicallyScopedActionFilter
cop
#5177
Conversation
def array_values(node) | ||
case node.type | ||
when :str | ||
[node.to_a[0]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use node.str_content.to_sym
for readability, and it needs .to_sym
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, probably we should add StrNode#value
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. This should be done with another pull request.
Could you add a test case to check array of strings? For example: before_action :something, only: %w[foo bar] Maybe the cop does not pass the test case now. |
[node.value] | ||
when :array | ||
node.values.map do |v| | ||
v.instance_of?(RuboCop::AST::SymbolNode) ? v.value : v |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be like the following.
node.values.map do |v|
case v.type
when :sym
v.value
when :str
v.str_content.to_sym
end
end.compact
I think the cop should ignore not-literal value.
And add test cases to check false positive. expect_no_offenses <<-RUBY
before_action :require_login, except: 'health_check'
def health_check
end
RUBY |
end | ||
end | ||
|
||
add_offense(node) unless @inexplicit_method_names.empty? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can use message:
keyword argument to avoid using the instance variable. Like add_offense(node, message: message(inexplicit_method_names))
Consider default resource(s) actions, that are # controller
class FooController < ApplicationController
before_action :require_login, only: :show
# empty action definition
end <!-- app/views/foo/show.html.erb -->
Hello, <%= current_user.name >!
So I think the cop should not add any offenses for these resource(s) actions. |
The name of the cop is pretty confusing, btw. It should be something like |
Thanks for feedback :)
Umm... I think that this example is not false positive :(
There are examples other than default resources that work without having to define methods on the same controller. The following example works correctly for # config/routes.rb
Rails.application.routes.draw do
get 'foo/bar'
end # controller
class FooController < ApplicationController
before_action :require_login, only: :bar
# empty action definition
end <!-- app/views/foo/bar.html.erb -->
Hello, <%= current_user.name >!
I think that it is undesirable to define filter dependent on such as routes or views.
The name is a very difficult problem... |
In the first version( efc1a5a ), I guess the cop added offense for the code, because the cop compared a string (in before_action) and symbol (in method definition). So I think we should have a test case for the case.
Oh, I see. I think it's confusing behaviour... |
a044280
to
42793b8
Compare
Rails/InexplicitFilter
copRails/LexicallyScopeActionFilter
cop
I renamed the cop name to |
42793b8
to
efc6b16
Compare
I made a typo - I meant to suggest |
methods_node = only_or_except_filter_methods(node) | ||
return unless methods_node | ||
|
||
defined_methods = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initializing an empty array and then pushing into it inside an #each
can be replaced with #map
. 馃檪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm, I wanted to use the type filter with #each_child_node
.
Perhaps #map_child_node
may be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I noticed that #each_child_node
will returnEnumerator
when not passing block. I will use this.
1eb02f1
to
ca375b0
Compare
Rails/LexicallyScopeActionFilter
copRails/LexicallyScopedActionFilter
cop
ca375b0
to
ec634ed
Compare
defined_methods = node.parent.each_child_node(:def).map(&:method_name) | ||
methods = array_values(methods_node).map do |method| | ||
method unless defined_methods.include?(method) | ||
end.compact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using reject
instead of map
will make compact
unnecessary.
methods = array_values(methods_node).reject do |method|
defined_methods.include?(method)
end
This cop checks that methods specified in the filter's `only` or `except` options are explicitly defined in the controller. You can specify methods of superclass or methods added by mixins on the filter, but these confuse developers. If you specify methods where are defined on another controller, you should define the filter in that controller.
ec634ed
to
6fa291f
Compare
@wata727 Maybe you should also add this as a suggestion to the Rails style guide. |
Thank you for this very useful cop @wata727 鉂わ笍 |
This cop checks that methods specified in the filter's
only
orexcept
options are explicitly defined in the controller.You can specify methods of superclass or methods added by mixins on the filter, but these confuse developers. If you specify methods where are defined on another controller, you should define the filter in that controller.
Also, as another advantage, you can notice the method name typo 馃槃
wdyt?
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).rake spec
) are passing.rake internal_investigation
.and description in grammatically correct, complete sentences.
rake generate_cops_documentation
(required only when you've added a new cop or changed the configuration/documentation of an existing cop).