class RuboCop::Cop::Rails::UniqBeforePluck
Model.distinct.pluck(:id)
# good
Model.pluck(:id).uniq
# bad
instance.assoc.pluck(:id).uniq
# an association on an instance will return a CollectionProxy
# bad
Model.where(cond: true).pluck(:id).uniq
# this will return a Relation that pluck is called on
# bad
@example EnforcedStyle: aggressive
Model.distinct.pluck(:id)
# good
Model.pluck(:id).uniq
# bad
@example EnforcedStyle: conservative (default)
false positives.
Autocorrect is disabled by default for this cop since it may generate
database collation.
This cop is unsafe because the behavior may change depending on the
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 distinct 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 within
Prefer the use of distinct, before pluck instead of after.
def dot_method_begin_pos(method, node)
def dot_method_begin_pos(method, node) lines = node.source.split(NEWLINE) if lines.last.strip == ".#{method}" node.source.rindex(NEWLINE) else node.loc.dot.begin_pos end end
def dot_method_with_whitespace(method, node)
def dot_method_with_whitespace(method, node) range_between(dot_method_begin_pos(method, node), node.loc.selector.end_pos) end
def on_send(node)
def on_send(node) method = if style == :conservative conservative_node_match(node) else aggressive_node_match(node) end return unless method add_offense(node.loc.selector) do |corrector| method = node.method_name corrector.remove(dot_method_with_whitespace(method, node)) corrector.insert_before(node.receiver.loc.dot.begin, '.distinct') end end
def style_parameter_name
def style_parameter_name 'EnforcedStyle' end