class RuboCop::Cop::Rails::Pick
[{ a: :b, c: :d }].pick(:a, :b)
Model.pick(:a)
# good
[{ a: :b, c: :d }].pluck(:a, :b).first
Model.pluck(:a).first
# bad
@example
See: github.com/rubocop/rubocop-rails/pull/249<br><br>in Rails 6.1 via rails/rails#38760, at which point the cop is safe.
whereas ‘pick` is only defined on `ActiveRecord::Relation` in Rails 6.0. This was addressed
This cop is unsafe because `pluck` is defined on both `ActiveRecord::Relation` and `Enumerable`,
@safety
care should be taken while resolving this violation.
causes a subquery to be added. In most cases this is undesirable, and
Note that when `pick` is added to a relation with an existing limit, it
limit to the query so that only one value is fetched from the database.
`pick` avoids. When called on an Active Record relation, `pick` adds a
Using `pluck` followed by `first` creates an intermediate array, which
Enforces the use of `pick` over `pluck(…).first`.
def message(receiver, current)
def message(receiver, current) format(MSG, args: receiver.arguments.map(&:source).join(', '), current: current.source) end
def on_send(node)
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