Class: LcpRuby::ModelFactory::AssociationApplicator

Inherits:
Object
  • Object
show all
Includes:
ManagedTracking
Defined in:
lib/lcp_ruby/model_factory/association_applicator.rb

Constant Summary

Constants included from ManagedTracking

ManagedTracking::EMPTY_SUMMARY

Instance Method Summary collapse

Methods included from ManagedTracking

reset_all!, #track!

Constructor Details

#initialize(model_class, model_definition, filter: :all) ⇒ AssociationApplicator

‘filter` controls which associations the applicator iterates:

:all (default) — every YAML association (current behavior, used by
  ModelFactory::Builder for dynamic LCP models).
:managed       — only associations marked `lcp_managed: true`,
  used by Engine.apply_bind_to_managed_associations to declare AR
  macros on bind_to: host classes. Suppresses
  accepts_nested_attributes_for so LCP does not silently install
  <assoc>_attributes= writers that may collide with host-defined
  attribute writers — host opts in by writing it themselves.


15
16
17
18
19
# File 'lib/lcp_ruby/model_factory/association_applicator.rb', line 15

def initialize(model_class, model_definition, filter: :all)
  @model_class = model_class
  @model_definition = model_definition
  @filter = filter
end

Instance Method Details

#apply!Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/lcp_ruby/model_factory/association_applicator.rb', line 21

def apply!
  associations_to_apply.each do |assoc|
    # Reload-safety guard: skip macro re-execution when LCP added
    # this association earlier in the same process. Tracking persists
    # across `Engine.reload!` (LcpRuby.reset! deliberately does not
    # wipe ManagedTracking), so a second apply! pass on the same
    # host class no-ops here. Without this, AR's belongs_to would
    # silently overwrite the reflection and stack duplicate callbacks
    # alongside the originals.
    next if @filter == :managed && already_managed?(assoc)

    installed = apply_association(assoc)
    # Track only when the macro was actually installed. apply_association
    # short-circuits at `target_def&.api_model?` and returns false —
    # without this guard we would record a never-installed assoc, then
    # on reload silently skip it, AND suppress a legitimate collision
    # error in the validator carve-out if the host later adds the macro
    # itself.
    track!(@model_class, :associations, assoc.name) if @filter == :managed && installed
  end
end