Class: MermaidRailsErd::ModelDataCollector

Inherits:
Object
  • Object
show all
Defined in:
lib/mermaid_rails_erd/model_data_collector.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model_loader) ⇒ ModelDataCollector

Returns a new instance of ModelDataCollector.



9
10
11
12
13
14
15
16
17
18
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 9

def initialize(model_loader)
  @models_data = {}
  @polymorphic_associations = []
  @regular_associations = []
  @invalid_associations = []
  @polymorphic_targets = Hash.new { |h, k| h[k] = [] }
  @tables = {}
  @models_no_tables = []
  @models = model_loader.load
end

Instance Attribute Details

#invalid_associationsObject (readonly)

Returns the value of attribute invalid_associations.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def invalid_associations
  @invalid_associations
end

#modelsObject (readonly)

Returns the value of attribute models.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def models
  @models
end

#models_dataObject (readonly)

Returns the value of attribute models_data.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def models_data
  @models_data
end

#models_no_tablesObject (readonly)

Returns the value of attribute models_no_tables.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def models_no_tables
  @models_no_tables
end

#polymorphic_associationsObject (readonly)

Returns the value of attribute polymorphic_associations.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def polymorphic_associations
  @polymorphic_associations
end

#regular_associationsObject (readonly)

Returns the value of attribute regular_associations.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def regular_associations
  @regular_associations
end

#tablesObject (readonly)

Returns the value of attribute tables.



7
8
9
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 7

def tables
  @tables
end

Instance Method Details

#collectObject



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
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 20

def collect
  (base_models & models_with_tables).each do |model|
    model_data = { model: model, associations: [] }

    # Register polymorphic interfaces that this model implements
    model.reflect_on_all_associations.each do |assoc|
      if (interface_name = assoc.options[:as])
        register_polymorphic_target(interface_name, model)
      end

      if assoc.options[:polymorphic]
        @polymorphic_associations << { model: model, association: assoc }
      else
        @regular_associations << { model: model, association: assoc }
      end

      model_data[:associations] << assoc
    end

    @models_data[model.name] = model_data

    collect_table_for_model(model)
  end

  (base_models & models_without_tables).each do |model|
    @models_no_tables << model
  end

  self
end

#collect_table_for_model(model) ⇒ Object

Collect table information from a model

Parameters:

  • model (Class)

    ActiveRecord model to collect table information from



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 76

def collect_table_for_model(model)
  # Skip if we've already collected this table
  return if @tables.key?(model.table_name)

  # Collect basic table structure with columns
  @tables[model.table_name] = model.columns.map do |col|
    annotations = []
    annotations << "PK" if col.name == model.primary_key

    ColumnInfo.new(col.name, annotations, col.sql_type, col.type, col.null)
  end
end

#get_model_data(model_name) ⇒ Object



51
52
53
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 51

def get_model_data(model_name)
  @models_data[model_name]
end

#polymorphic_targets_for(polymorphic_name) ⇒ Array<Class>

Returns all models that implement the given polymorphic interface

Parameters:

  • polymorphic_name (String, Symbol)

    Name of the polymorphic interface

Returns:

  • (Array<Class>)

    Array of models that implement the interface



65
66
67
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 65

def polymorphic_targets_for(polymorphic_name)
  @polymorphic_targets[polymorphic_name.to_s] || []
end

#register_invalid_association(model, assoc, reason = nil) ⇒ Object

Register an invalid association that couldn’t be resolved

Parameters:

  • model (Class)

    Model containing the invalid association

  • assoc (ActiveRecord::Reflection::Association)

    Invalid association

  • reason (String) (defaults to: nil)

    Reason why the association is invalid



114
115
116
117
118
119
120
121
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 114

def register_invalid_association(model, assoc, reason = nil)
  @invalid_associations << {
    model: model,
    association: assoc,
    reason: reason,
    label: "#{model.name}##{assoc.name}",
  }
end

#register_polymorphic_target(interface_name, model) ⇒ Object

Register a model as implementing a polymorphic interface

Parameters:

  • interface_name (String, Symbol)

    Name of the polymorphic interface

  • model (Class)

    Model that implements the interface



58
59
60
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 58

def register_polymorphic_target(interface_name, model)
  @polymorphic_targets[interface_name.to_s] << model
end

#reset_polymorphic_targetsObject

Reset all registered polymorphic targets (useful for testing)



70
71
72
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 70

def reset_polymorphic_targets
  @polymorphic_targets.clear
end

#update_foreign_keys(relationships) ⇒ Hash

Update table definitions with foreign key annotations

Parameters:

  • relationships (Array<Relationship>)

    List of relationships to extract FKs from

Returns:

  • (Hash)

    Updated tables hash



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/mermaid_rails_erd/model_data_collector.rb', line 92

def update_foreign_keys(relationships)
  fk_mapping = extract_foreign_keys(relationships)

  @tables.each do |table_name, columns|
    next unless fk_mapping[table_name]

    begin
      columns.each do |col|
        col.annotations << "FK" if fk_mapping[table_name].include?(col.name) && !col.annotations.include?("FK")
      end
    rescue StandardError => e
      puts "Error updating FK annotations for #{table_name}: #{e.message}"
    end
  end

  @tables
end