class RuboCop::Cop::Rails::UniqBeforePluck
customer.favourites.distinct.pluck(:color)
Album.distinct.where(year: 1985).pluck(:band_name)
Album.distinct.pluck(:band_name)
# good
customer.favourites.pluck(:color).uniq
# bad - redundantly fetches duplicate values
Album.where(year: 1985).pluck(:band_name).uniq
# bad - redundantly fetches duplicate values
Album.pluck(:band_name).uniq
# bad - redundantly fetches duplicate values
@example EnforcedStyle: aggressive
Album.distinct.pluck(:band_name)
# good
Album.pluck(:band_name).uniq
# bad - redundantly fetches duplicate values
@example EnforcedStyle: conservative (default)
depending on the database collation.
This cop is unsafe for autocorrection because the behavior may change
@safety
ActiveRecord::Associations::CollectionProxy.
ActiveRecord::Relation vs a call to pluck on an
as the cop cannot distinguish between calls to ‘pluck` on an
distinct are added as offenses. This may lead to false positives
When the EnforcedStyle is `aggressive` then all calls to `pluck` before
(i.e. a model class) before `uniq` are added as offenses.
is `conservative` (the default), then only calls to `pluck` on a constant
This cop has two different enforcement modes. When the EnforcedStyle
the database.
The use of distinct before pluck is preferred because it executes by
Prefer using `distinct` before `pluck` instead of `uniq` after `pluck`.
def autocorrect(corrector, uniq_node, pluck_node)
def autocorrect(corrector, uniq_node, pluck_node) corrector.remove(range_between(pluck_node.loc.end.end_pos, uniq_node.loc.selector.end_pos)) if (dot = pluck_node.loc.dot) corrector.insert_before(dot.begin, '.distinct') else corrector.insert_before(pluck_node, 'distinct.') end end
def on_send(node)
def on_send(node) uniq_before_pluck(node) do |uniq_node, pluck_node| next if style == :conservative && !pluck_node.receiver&.const_type? add_offense(uniq_node.loc.selector) do |corrector| autocorrect(corrector, uniq_node, pluck_node) end end end