class RuboCop::Cop::Rails::RedundantReceiverInWithOptions
end
end
merger.invoke(another_receiver)
with_another_method do |another_receiver|
merger.invoke
with_options options: false do |merger|
# receiver.
# cannot be evaluated. Thus, it is ok to include the explicit
# When ‘with_options` includes a block, all scoping scenarios
# ok
end
client.invoke(merger.something, something)
with_options options: false do |merger|
client = Client.new
# good
end
invoke(something)
with_options options: false do
# good
end
merger.invoke(merger.something)
with_options options: false do |merger|
# bad
@example
end
end
has_many :expenses
has_many :invoices
has_many :products
has_many :customers
with_options dependent: :destroy do
class Account < ApplicationRecord
# good
end
end
assoc.has_many :expenses
assoc.has_many :invoices
assoc.has_many :products
assoc.has_many :customers
with_options dependent: :destroy do |assoc|
class Account < ApplicationRecord
# bad
@example
Receiver is implicit from Rails 4.2 or higher.
Checks for redundant receiver in `with_options`.
def autocorrect(corrector, send_node, node)
def autocorrect(corrector, send_node, node) corrector.remove(send_node.receiver) corrector.remove(send_node.loc.dot) corrector.remove(block_argument_range(send_node)) if node.block_type? end
def block_argument_range(node)
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
def on_block(node)
def on_block(node) return unless node.method?(:with_options) return unless (body = node.body) return unless all_block_nodes_in(body).count.zero? send_nodes = all_send_nodes_in(body) return unless redundant_receiver?(send_nodes, node) send_nodes.each do |send_node| receiver = send_node.receiver add_offense(receiver) do |corrector| autocorrect(corrector, send_node, node) end end end
def redundant_receiver?(send_nodes, node)
def redundant_receiver?(send_nodes, node) proc = if node.numblock_type? ->(n) { n.receiver.lvar_type? && n.receiver.source == '_1' } elsif node.itblock_type? ->(n) { n.receiver.lvar_type? && n.receiver.source == 'it' } else return false if node.arguments.empty? arg = node.first_argument ->(n) { same_value?(arg, n.receiver) } end send_nodes.all?(&proc) end
def same_value?(arg_node, recv_node)
def same_value?(arg_node, recv_node) recv_node && recv_node.children[0] == arg_node.children[0] end
def search_begin_pos_of_space_before_block_argument(begin_pos)
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