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