Class: RuboCop::Cop::Rails::UniqBeforePluck

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
ConfigurableEnforcedStyle, RangeHelp
Defined in:
lib/rubocop/cop/rails/uniq_before_pluck.rb

Overview

Prefer using ‘distinct` before `pluck` instead of `uniq` after `pluck`.

The use of distinct before pluck is preferred because it executes by the database.

This cop has two different enforcement modes. When the EnforcedStyle is ‘conservative` (the default), then only calls to `pluck` on a constant (i.e. a model class) before `uniq` are added as offenses.

When the EnforcedStyle is ‘aggressive` then all calls to `pluck` before distinct are added as offenses. This may lead to false positives as the cop cannot distinguish between calls to `pluck` on an ActiveRecord::Relation vs a call to pluck on an ActiveRecord::Associations::CollectionProxy.

Examples:

EnforcedStyle: conservative (default)

# bad - redundantly fetches duplicate values
Album.pluck(:band_name).uniq

# good
Album.distinct.pluck(:band_name)

EnforcedStyle: aggressive

# bad - redundantly fetches duplicate values
Album.pluck(:band_name).uniq

# bad - redundantly fetches duplicate values
Album.where(year: 1985).pluck(:band_name).uniq

# bad - redundantly fetches duplicate values
customer.favourites.pluck(:color).uniq

# good
Album.distinct.pluck(:band_name)
Album.distinct.where(year: 1985).pluck(:band_name)
customer.favourites.distinct.pluck(:color)

Constant Summary collapse

MSG =
'Use `distinct` before `pluck`.'
RESTRICT_ON_SEND =
%i[uniq].freeze
NEWLINE =
"\n"
PATTERN =
'[!^block (send (send %<type>s :pluck ...) :uniq ...)]'

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rubocop/cop/rails/uniq_before_pluck.rb', line 61

def on_send(node)
  uniq = if style == :conservative
           conservative_node_match(node)
         else
           aggressive_node_match(node)
         end

  return unless uniq

  add_offense(node.loc.selector) do |corrector|
    autocorrect(corrector, node)
  end
end