Class: RuboCop::Cop::Rails::Pick

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector, TargetRailsVersion
Defined in:
lib/rubocop/cop/rails/pick.rb

Overview

Enforces the use of ‘pick` over `pluck(…).first`.

Using ‘pluck` followed by `first` creates an intermediate array, which `pick` avoids. When called on an Active Record relation, `pick` adds a limit to the query so that only one value is fetched from the database.

Note that when ‘pick` is added to a relation with an existing limit, it causes a subquery to be added. In most cases this is undesirable, and care should be taken while resolving this violation.

Examples:

# bad
Model.pluck(:a).first
[{ a: :b, c: :d }].pluck(:a, :b).first

# good
Model.pick(:a)
[{ a: :b, c: :d }].pick(:a, :b)

Constant Summary collapse

MSG =
'Prefer `pick(%<args>s)` over `%<current>s`.'
RESTRICT_ON_SEND =
%i[first].freeze

Constants included from TargetRailsVersion

TargetRailsVersion::TARGET_GEM_NAME, TargetRailsVersion::USES_REQUIRES_GEM_API

Instance Method Summary collapse

Methods included from TargetRailsVersion

minimum_target_rails_version, support_target_rails_version?

Instance Method Details

#on_send(node) ⇒ Object Also known as: on_csend



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rubocop/cop/rails/pick.rb', line 44

def on_send(node)
  pick_candidate?(node) do
    receiver = node.receiver
    receiver_selector = receiver.loc.selector
    node_selector = node.loc.selector
    range = receiver_selector.join(node_selector)

    add_offense(range, message: message(receiver, range)) do |corrector|
      first_range = receiver.source_range.end.join(node_selector)

      corrector.remove(first_range)
      corrector.replace(receiver_selector, 'pick')
    end
  end
end