class RailsBestPractices::Reviews::NeedlessDeepNestingReview

Review config/routes.rb file to make sure not to use too deep nesting routes.

See the best practice details here rails-bestpractices.com/posts/2010/07/22/needless-deep-nesting/

Implementation:

Review process:

chech all method_add_block nodes in route file.

it is a recursively check in method_add_block node,

if it is a method_add_block node,
increment @counter at the beginning of resources,
decrement @counter at the end of resrouces,
recursively check nodes in block body.

if the child node is a command_call or command node,
and the message of the node is "resources" or "resource",
and the @counter is greater than @nested_count defined,
then it is a needless deep nesting.

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/rails_best_practices/reviews/needless_deep_nesting_review.rb, line 30
def initialize(options = {})
  super(options)
  @counter = 0
  @nested_count = options['nested_count'] || 2
  @shallow_nodes = []
end

Private Instance Methods

recursively_check(node) click to toggle source

check nested route.

if the receiver of the method_add_block is with message “resources” or “resource”, then increment the @counter, recursively check the block body, and decrement the @counter.

if the node type is command_call or command, and its message is resources or resource, then check if @counter is greater than or equal to @nested_count, if so, it is the needless deep nesting.

# File lib/rails_best_practices/reviews/needless_deep_nesting_review.rb, line 63
def recursively_check(node)
  shallow = @shallow_nodes.include? node

  if %i[command_call command].include?(node[1].sexp_type) && %w[resources resource].include?(node[1].message.to_s)
    hash_node = node[1].arguments.grep_node(sexp_type: :bare_assoc_hash)
    shallow ||= (hash_node && hash_node.hash_value('shallow').to_s == 'true')
    @counter += 1
    node.block_node.statements.each do |stmt_node|
      @shallow_nodes << stmt_node if shallow
      recursively_check(stmt_node)
    end
    @counter -= 1
  elsif %i[command_call command].include?(node.sexp_type) && %w[resources resource].include?(node.message.to_s)
    add_error "needless deep nesting (nested_count > #{@nested_count})", @file, node.line_number if @counter >=
      @nested_count && !@shallow_nodes.include?(node)
  end
end