File: avoid_using_pluck_without_limit.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (53 lines) | stat: -rw-r--r-- 1,542 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 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

        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