class RuboCop::Cop::Rails::RedundantReceiverInWithOptions

This cop checks for redundant receiver in `with_options`. Receiver is implicit from Rails 4.2 or higher.

@example

# bad
class Account < ApplicationRecord
  with_options dependent: :destroy do |assoc|
    assoc.has_many :customers
    assoc.has_many :products
    assoc.has_many :invoices
    assoc.has_many :expenses
  end
end

# good
class Account < ApplicationRecord
  with_options dependent: :destroy do
    has_many :customers
    has_many :products
    has_many :invoices
    has_many :expenses
  end
end

@example

# bad
with_options options: false do |merger|
  merger.invoke(merger.something)
end

# good
with_options options: false do
  invoke(something)
end

# good
client = Client.new
with_options options: false do |merger|
  client.invoke(merger.something, something)
end

# ok
# When `with_options` includes a block, all scoping scenarios
# cannot be evaluated. Thus, it is ok to include the explicit
# receiver.
with_options options: false do |merger|
  merger.invoke
  with_another_method do |another_receiver|
    merger.invoke(another_receiver)
  end
end

Constants

MSG

Public Instance Methods

on_block(node) click to toggle source
# File lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb, line 80
def on_block(node)
  with_options?(node) do |arg, body|
    return if body.nil?
    return unless all_block_nodes_in(body).count.zero?

    send_nodes = all_send_nodes_in(body)

    if send_nodes.all? { |n| same_value?(arg, n.receiver) }
      send_nodes.each do |send_node|
        receiver = send_node.receiver
        add_offense(receiver.source_range) do |corrector|
          autocorrect(corrector, send_node)
        end
      end
    end
  end
end

Private Instance Methods

autocorrect(corrector, node) click to toggle source
# File lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb, line 100
def autocorrect(corrector, node)
  corrector.remove(node.receiver.source_range)
  corrector.remove(node.loc.dot)
  corrector.remove(block_argument_range(node))
end
block_argument_range(node) click to toggle source
# File lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb, line 106
def block_argument_range(node)
  block_node = node.each_ancestor(:block).first
  block_argument = block_node.children[1].source_range

  range_between(
    search_begin_pos_of_space_before_block_argument(
      block_argument.begin_pos
    ),
    block_argument.end_pos
  )
end
same_value?(arg_node, recv_node) click to toggle source
# File lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb, line 128
def same_value?(arg_node, recv_node)
  recv_node && recv_node.children[0] == arg_node.children[0]
end
search_begin_pos_of_space_before_block_argument(begin_pos) click to toggle source
# File lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb, line 118
def search_begin_pos_of_space_before_block_argument(begin_pos)
  position = begin_pos - 1

  if processed_source.raw_source[position] == ' '
    search_begin_pos_of_space_before_block_argument(position)
  else
    begin_pos
  end
end