Class: RuboCop::Cop::Rails::Pluck
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Rails::Pluck
- Extended by:
- AutoCorrector, TargetRailsVersion
- Defined in:
- lib/rubocop/cop/rails/pluck.rb
Overview
Enforces the use of ‘pluck` over `map`.
‘pluck` can be used instead of `map` to extract a single key from each element in an enumerable. When called on an Active Record relation, it results in a more efficient query that only selects the necessary key.
NOTE: If the receiver’s relation is not loaded and ‘pluck` is used inside an iteration, it may result in N+1 queries because `pluck` queries the database on each iteration. This cop ignores offenses for `map/collect` when they are suspected to be part of an iteration to prevent such potential issues.
- source,ruby
users = User.all 5.times do
users.map { |user| user[:foo] } # Only one query is executed
end
users = User.all 5.times do
users.pluck(:id) # A query is executed on every iteration
end
If a method call has no receiver, like ‘do_something { users.map { |user| user }`, it is not considered part of an iteration and will be detected.
Constant Summary collapse
- MSG =
'Prefer `%<replacement>s` over `%<current>s`.'
Constants included from TargetRailsVersion
TargetRailsVersion::TARGET_GEM_NAME, TargetRailsVersion::USES_REQUIRES_GEM_API
Instance Method Summary collapse
-
#on_block(node) ⇒ Object
(also: #on_numblock, #on_itblock)
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
Methods included from TargetRailsVersion
minimum_target_rails_version, support_target_rails_version?
Instance Method Details
#on_block(node) ⇒ Object Also known as: on_numblock, on_itblock
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rubocop/cop/rails/pluck.rb', line 66 def on_block(node) return if node.each_ancestor(:any_block).first&.receiver pluck_candidate?(node) do |argument, key| next if key.regexp_type? || !use_one_block_argument?(argument) match = if node.block_type? block_argument = argument.children.first.source use_block_argument_in_key?(block_argument, key) elsif node.numblock_type? use_block_argument_in_key?('_1', key) else # itblock use_block_argument_in_key?('it', key) end next unless match register_offense(node, key) end end |