Class: RailsBestPractices::Reviews::UseBeforeFilterReview

Inherits:
Review show all
Defined in:
lib/rails_best_practices/reviews/use_before_filter_review.rb

Overview

Review a controller file to make sure to use before_filter to remove duplicated first code line in different action.

See the best practice detailed here rails-bestpractices.com/posts/22-use-before_filter.

Implementation:

Review process:

check all first code line in method definitions (actions),
if they are duplicated, then they should be moved to before_filter.

Constant Summary collapse

PROTECTED_PRIVATE_CALLS =
[[:call, nil, :protected, [:arglist]], [:call, nil, :private, [:arglist]]]

Constants inherited from Core::Check

Core::Check::CONTROLLER_FILES, Core::Check::HELPER_FILES, Core::Check::MAILER_FILES, Core::Check::MIGRATION_FILES, Core::Check::MODEL_FILES, Core::Check::NODE_TYPES, Core::Check::PARTIAL_VIEW_FILES, Core::Check::ROUTE_FILE, Core::Check::SCHEMA_FILE, Core::Check::VIEW_FILES

Instance Attribute Summary

Attributes inherited from Core::Check

#errors

Instance Method Summary collapse

Methods inherited from Review

#equal?, #model_associations, #model_attributes, #models, #remember_variable_use_count, #reset_variable_use_count, #variable, #variable_use_count

Methods inherited from Core::Check

#add_error, #method_missing, #node_end, #node_start

Constructor Details

#initialize(options = {}) ⇒ UseBeforeFilterReview

Returns a new instance of UseBeforeFilterReview.



31
32
33
34
# File 'lib/rails_best_practices/reviews/use_before_filter_review.rb', line 31

def initialize(options = {})
  super()
  @customize_count = options['customize_count'] || 1
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RailsBestPractices::Core::Check

Instance Method Details

#interesting_filesObject



27
28
29
# File 'lib/rails_best_practices/reviews/use_before_filter_review.rb', line 27

def interesting_files
  CONTROLLER_FILES
end

#interesting_nodesObject



23
24
25
# File 'lib/rails_best_practices/reviews/use_before_filter_review.rb', line 23

def interesting_nodes
  [:class]
end

#start_class(class_node) ⇒ Object

check class define node to see if there are method define nodes whose first code line are duplicated.

it will check every defn nodes in the class node until protected or private identification, if there are defn nodes who have the same first code line, like

s(:class, :PostsController, s(:const, :ApplicationController),
  s(:scope,
    s(:block,
      s(:defn, :show, s(:args),
        s(:scope,
          s(:block,
            s(:iasgn, :@post,
              s(:call,
                s(:call, s(:call, nil, :current_user, s(:arglist)), :posts, s(:arglist)),
                :find,
                s(:arglist,
                  s(:call, s(:call, nil, :params, s(:arglist)), :[], s(:arglist, s(:lit, :id)))
                )
              )
            )
          )
        )
      ),
      s(:defn, :edit, s(:args),
        s(:scope,
          s(:block,
            s(:iasgn, :@post,
              s(:call,
                s(:call, s(:call, nil, :current_user, s(:arglist)), :posts, s(:arglist)),
                :find,
                s(:arglist,
                  s(:call, s(:call, nil, :params, s(:arglist)), :[], s(:arglist, s(:lit, :id)))
                )
              )
            )
          )
        )
      )
    )
  )
)

then these duplicated first code lines should be moved to before_filter.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rails_best_practices/reviews/use_before_filter_review.rb', line 79

def start_class(class_node)
  @first_sentences = {}

  class_node.body.children.each do |child_node|
    break if PROTECTED_PRIVATE_CALLS.include? child_node
    remember_first_sentence(child_node) if :defn == child_node.node_type
  end
  @first_sentences.each do |first_sentence, defn_nodes|
    if defn_nodes.size > @customize_count
      add_error "use before_filter for #{defn_nodes.collect(&:method_name).join(',')}", class_node.file, defn_nodes.collect(&:line).join(',')
    end
  end
end

#urlObject



19
20
21
# File 'lib/rails_best_practices/reviews/use_before_filter_review.rb', line 19

def url
  "http://rails-bestpractices.com/posts/22-use-before_filter"
end