Files
gitlab-foss/rubocop/cop/database/avoid_using_pluck_without_limit.rb
2025-06-16 06:13:56 +00:00

55 lines
1.5 KiB
Ruby

# frozen_string_literal: true
require 'rubocop/cop/mixin/active_record_helper'
require_relative '../../code_reuse_helpers'
module RuboCop
module Cop
module Database
# Checks the use of .pluck(:attribute) without setting a limit.
#
# @example
#
# # bad
# def all
# Project.where(user_id: User.pluck(:id))
# end
#
# # good
# def all(limit)
# Project.where(user_id: User.limit(limit).pluck(:id))
# end
class AvoidUsingPluckWithoutLimit < RuboCop::Cop::Base
include RuboCop::Cop::ActiveRecordHelper
include RuboCop::CodeReuseHelpers
MSG = 'Avoid using `pluck` without defining a proper `limit`. ' \
'Querying with too much values inside an `IN` clause can result in database performance degradation. ' \
'See https://gitlab.com/gitlab-com/gl-infra/production/-/issues/17168'
RESTRICT_ON_SEND = %i[pluck].freeze
# @!method pluck_with_limit?(node)
def_node_matcher :pluck_with_limit?, <<~PATTERN
(send (send _ :limit _) ...)
PATTERN
def on_send(node)
return unless should_scan?(node)
return if pluck_with_limit?(node)
add_offense(node.loc.selector)
end
private
# It limits the check to ActiveRecord, Models, Finders and Service classes
def should_scan?(node)
inherit_active_record_base?(node) || in_model?(node) || in_finder?(node) || in_service_class?(node)
end
end
end
end
end