Class: EagerEye::Detectors::LoopAssociation

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

Constant Summary collapse

ITERATION_METHODS =
%i[each map collect select find find_all reject filter filter_map flat_map].freeze
PRELOAD_METHODS =
%i[includes preload eager_load].freeze
SINGLE_RECORD_METHODS =

Methods that return a single record (not a collection)

%i[find find_by find_by! first first! last last! take take! second third fourth fifth
forty_two sole find_sole_by].freeze
ASSOCIATION_NAMES =

Common association names (belongs_to = singular, has_many = plural)

Set.new(%w[
  author user owner creator admin member customer client post article comment category tag
  parent company organization project task item order product account profile setting image
  avatar photo attachment document authors users owners creators admins members customers
  clients posts articles comments categories tags children companies organizations projects
  tasks items orders products accounts profiles settings images avatars photos attachments
  documents
]).freeze
EXCLUDED_METHODS =

Methods that should NOT be treated as associations

%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
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.detector_nameObject



30
31
32
# File 'lib/eager_eye/detectors/loop_association.rb', line 30

def self.detector_name
  :loop_association
end

Instance Method Details

#detect(ast, file_path) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/eager_eye/detectors/loop_association.rb', line 34

def detect(ast, file_path)
  return [] unless ast

  issues = []
  build_variable_maps(ast)

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

    block_var = extract_block_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 = extract_included_associations(collection_node)
    included.merge(extract_variable_preloads(collection_node))

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

  issues
end