Class: RuboCop::Cop::Rails::LexicallyScopedActionFilter

Inherits:
Cop
  • Object
show all
Defined in:
lib/rubocop/cop/rails/lexically_scoped_action_filter.rb

Overview

This cop checks that methods specified in the filter's `only` or `except` options are defined within the same class or module.

You can technically specify methods of superclass or methods added by mixins on the filter, but these confuse developers. If you specify methods that are defined in other classes or modules, you should define the filter in that class or module.

Examples:

# bad
class LoginController < ApplicationController
  before_action :require_login, only: %i[index settings logout]

  def index
  end
end

# good
class LoginController < ApplicationController
  before_action :require_login, only: %i[index settings logout]

  def index
  end

  def settings
  end

  def logout
  end
end
# bad
module FooMixin
  extend ActiveSupport::Concern

  included do
    before_action proc { authenticate }, only: :foo
  end
end

# good
module FooMixin
  extend ActiveSupport::Concern

  included do
    before_action proc { authenticate }, only: :foo
  end

  def foo
    # something
  end
end

Constant Summary collapse

MSG =
'%<action>s not explicitly defined on the %<type>s.'.freeze
FILTERS =
%w[
  :after_action
  :append_after_action
  :append_around_action
  :append_before_action
  :around_action
  :before_action
  :prepend_after_action
  :prepend_around_action
  :prepend_before_action
  :skip_after_action
  :skip_around_action
  :skip_before_action
  :skip_action_callback
].freeze

Constants included from Util

Util::LITERAL_REGEX

Instance Attribute Summary

Attributes inherited from Cop

#config, #corrections, #offenses, #processed_source

Instance Method Summary collapse

Methods inherited from Cop

#add_offense, all, autocorrect_incompatible_with, badge, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, #correct, department, #duplicate_location?, #excluded_file?, #find_location, #highlights, inherited, #initialize, #join_force?, lint?, match?, #messages, non_rails, #parse, qualified_cop_name, #relevant_file?, #target_rails_version, #target_ruby_version

Methods included from NodePattern::Macros

#def_node_matcher, #def_node_search, #node_search, #node_search_all, #node_search_body, #node_search_first

Methods included from AST::Sexp

#s

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #support_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

begins_its_line?, comment_line?, double_quotes_required?, escape_string, first_part_of_call_chain, interpret_string_escapes, line_range, needs_escaping?, on_node, parentheses?, same_line?, to_string_literal, to_supported_styles, tokens

Methods included from PathUtil

absolute?, hidden_dir?, hidden_file_in_not_hidden_dir?, match_path?, pwd, relative_path, reset_pwd, smart_path

Constructor Details

This class inherits a constructor from RuboCop::Cop::Cop

Instance Method Details

#on_send(node) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rubocop/cop/rails/lexically_scoped_action_filter.rb', line 89

def on_send(node)
  methods_node = only_or_except_filter_methods(node)
  return unless methods_node

  parent = node.each_ancestor(:class, :module).first
  return unless parent

  block = parent.each_child_node(:begin).first
  return unless block

  defined_methods = block.each_child_node(:def).map(&:method_name)
  methods = array_values(methods_node).reject do |method|
    defined_methods.include?(method)
  end

  message = message(methods, parent)
  add_offense(node, message: message) unless methods.empty?
end