Class: EagerEye::Detectors::LoopAssociation

Inherits:
Base
  • Object
show all
Includes:
Concerns::VariableModelInference
Defined in:
lib/eager_eye/detectors/loop_association.rb

Overview

rubocop:disable Metrics/ClassLength

Constant Summary collapse

ITERATION_METHODS =
%i[each map collect select find find_all reject filter filter_map flat_map
each_with_index each_with_object reduce inject
find_each find_in_batches in_batches array!].freeze
PRELOAD_METHODS =
%i[includes preload eager_load].freeze
SINGLE_RECORD_METHODS =
%i[find find_by find_by! first first! last last! take take! second third fourth fifth
forty_two sole find_sole_by].freeze
NON_LOADING_TERMINAL_METHODS =

Terminal methods on an association that do NOT trigger a SELECT for loading the association — they translate directly to UPDATE/DELETE SQL against the association’s foreign key.

%i[update_all delete_all destroy_all touch_all
increment_counter decrement_counter].freeze
ASSOCIATION_NAMES =
Set.new(%w[
  author user owner creator admin member customer client post article comment category
  parent company organization project task item order product account profile
  avatar photo authors users owners creators admins members customers
  clients posts articles comments categories children companies organizations projects
  tasks items orders products accounts profiles avatars photos
]).freeze
EXCLUDED_METHODS =
%i[
  id to_s to_h to_a to_json to_xml inspect class object_id nil? blank? present? empty?
  any? none? size count length save save! update update! destroy destroy! delete delete!
  valid? invalid? errors new? persisted? changed? frozen? name title body content text
  description value key type status state created_at updated_at deleted_at origin
  priority level kind label code reason amount price quantity url path email phone
  address notes memo data metadata position rank score rating enabled disabled active
  published draft archived locked visible hidden tag image attachment document setting
].freeze

Constants included from Concerns::VariableModelInference

Concerns::VariableModelInference::PAGINATION_META_NAMES, Concerns::VariableModelInference::RELATION_WRAPPERS

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

default_severity

Class Method Details

.detector_nameObject



38
39
40
# File 'lib/eager_eye/detectors/loop_association.rb', line 38

def self.detector_name
  :loop_association
end

Instance Method Details

#detect(ast, file_path, association_preloads = {}, association_names = Set.new, method_queries = {}, associations_by_model = {}) ⇒ Object

rubocop:disable Metrics/ParameterLists



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/eager_eye/detectors/loop_association.rb', line 42

def detect(ast, file_path, association_preloads = {}, association_names = Set.new, # rubocop:disable Metrics/ParameterLists
           method_queries = {}, associations_by_model = {})
  return [] unless ast

  issues = []
  @association_preloads = association_preloads
  @dynamic_associations = association_names
  @method_queries = method_queries
  @associations_by_model = associations_by_model
  build_variable_maps(ast)

  traverse_ast(ast) do |node|
    next unless iteration_block?(node)

    block_var = extract_iteration_variable(node)
    next unless block_var

    block_body = node.children[2]
    next unless block_body

    collection_node = node.children[0]
    next if single_record_iteration?(collection_node)

    included = collect_included_associations(collection_node)
    model_name = infer_model_from_value(collection_node)
    skip_nodes = collect_non_loading_skip_set(block_body)

    find_association_calls(block_body, block_var, file_path, issues, included, model_name, skip_nodes)
  end

  issues
end