lib/rubocop/cop/rails/uniq_before_pluck.rb in rubocop-rails-2.12.4 vs lib/rubocop/cop/rails/uniq_before_pluck.rb in rubocop-rails-2.13.0
- old
+ new
@@ -1,90 +1,84 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
- # Prefer the use of distinct, before pluck instead of after.
+ # Prefer using `distinct` before `pluck` instead of `uniq` after `pluck`.
#
- # The use of distinct before pluck is preferred because it executes within
+ # 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 distinct are added as offenses.
+ # 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
+ # 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
+ # as the cop cannot distinguish between calls to `pluck` on an
# ActiveRecord::Relation vs a call to pluck on an
# ActiveRecord::Associations::CollectionProxy.
#
- # This cop is unsafe because the behavior may change depending on the
- # database collation.
- # Autocorrect is disabled by default for this cop since it may generate
- # false positives.
+ # @safety
+ # This cop is unsafe for autocorrection because the behavior may change
+ # depending on the database collation.
#
# @example EnforcedStyle: conservative (default)
- # # bad
- # Model.pluck(:id).uniq
+ # # bad - redundantly fetches duplicate values
+ # Album.pluck(:band_name).uniq
#
# # good
- # Model.distinct.pluck(:id)
+ # Album.distinct.pluck(:band_name)
#
# @example EnforcedStyle: aggressive
- # # bad
- # # this will return a Relation that pluck is called on
- # Model.where(cond: true).pluck(:id).uniq
+ # # bad - redundantly fetches duplicate values
+ # Album.pluck(:band_name).uniq
#
- # # bad
- # # an association on an instance will return a CollectionProxy
- # instance.assoc.pluck(:id).uniq
+ # # bad - redundantly fetches duplicate values
+ # Album.where(year: 1985).pluck(:band_name).uniq
#
- # # bad
- # Model.pluck(:id).uniq
+ # # bad - redundantly fetches duplicate values
+ # customer.favourites.pluck(:color).uniq
#
# # good
- # Model.distinct.pluck(:id)
+ # Album.distinct.pluck(:band_name)
+ # Album.distinct.where(year: 1985).pluck(:band_name)
+ # customer.favourites.distinct.pluck(:color)
#
class UniqBeforePluck < Base
include ConfigurableEnforcedStyle
include RangeHelp
extend AutoCorrector
MSG = 'Use `distinct` before `pluck`.'
- RESTRICT_ON_SEND = %i[uniq distinct pluck].freeze
+ RESTRICT_ON_SEND = %i[uniq].freeze
NEWLINE = "\n"
- PATTERN = '[!^block (send (send %<type>s :pluck ...) ' \
- '${:uniq :distinct} ...)]'
+ PATTERN = '[!^block (send (send %<type>s :pluck ...) :uniq ...)]'
def_node_matcher :conservative_node_match,
format(PATTERN, type: 'const')
def_node_matcher :aggressive_node_match,
format(PATTERN, type: '_')
def on_send(node)
- method = if style == :conservative
- conservative_node_match(node)
- else
- aggressive_node_match(node)
- end
+ uniq = if style == :conservative
+ conservative_node_match(node)
+ else
+ aggressive_node_match(node)
+ end
- return unless method
+ return unless uniq
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
private
-
- def style_parameter_name
- 'EnforcedStyle'
- end
def dot_method_with_whitespace(method, node)
range_between(dot_method_begin_pos(method, node),
node.loc.selector.end_pos)
end