Class: TypedEAV::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/typed_eav/registry.rb

Overview

Registry of entity types (host ActiveRecord models) that have opted into typed fields via has_typed_eav. Tracks optional field-type restrictions per entity.

Populated automatically when a host model calls has_typed_eav; read by Field::Base#validate_type_allowed_for_entity to enforce restrictions on field creation.

Implementation note: see Config for why the class-level accessor is hand-rolled rather than provided by ActiveSupport::Configurable.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.entitiesObject

Mutable registry of entity_type => [...] entries. Lazy-init so first access seeds an empty Hash; reset! clears in place so the same Hash object is preserved across resets (callers that captured a reference don't end up with a stale snapshot).



20
21
22
# File 'lib/typed_eav/registry.rb', line 20

def entities
  @entities ||= {}
end

Class Method Details

.allowed_types_for(entity_type) ⇒ Object

Field-type restrictions for a given entity, or nil if unrestricted.



50
51
52
53
54
55
# File 'lib/typed_eav/registry.rb', line 50

def allowed_types_for(entity_type)
  entry = entities[entity_type]
  return nil unless entry

  entry[:types]
end

.entity_typesObject

All registered entity type names.



45
46
47
# File 'lib/typed_eav/registry.rb', line 45

def entity_types
  entities.keys
end

.register(entity_type, types: nil, versioned: false) ⇒ Object

Register an entity type with optional type restrictions and optional versioning opt-in.

versioned: is the per-entity opt-in flag. When true and the boot-latched transactional callbacks are installed, the version writer records a TypedEAV::ValueVersion row per Value mutation on this entity_type. Default false — apps not using versioning pay zero version-row work.

Backward compat: existing callers register(name, types: types) continue to work — the new kwarg defaults to false. The entry hash shape changes from { types: types } to { types: types, versioned: versioned }, but consumers (Registry.allowed_types_for, Registry.type_allowed?) only read the :types key, so they're unaffected.



40
41
42
# File 'lib/typed_eav/registry.rb', line 40

def register(entity_type, types: nil, versioned: false)
  entities[entity_type] = { types: types, versioned: versioned }
end

.reset!Object

Clear all registrations (test isolation).



85
86
87
# File 'lib/typed_eav/registry.rb', line 85

def reset!
  entities.clear
end

.type_allowed?(entity_type, field_type_class) ⇒ Boolean

Whether a field type class is allowed for an entity.

Returns:

  • (Boolean)


58
59
60
61
62
63
64
# File 'lib/typed_eav/registry.rb', line 58

def type_allowed?(entity_type, field_type_class)
  allowed = allowed_types_for(entity_type)
  return true if allowed.nil?

  type_name = field_type_class.name.demodulize.underscore.to_sym
  allowed.include?(type_name)
end

.versioned?(entity_type) ⇒ Boolean

Whether the entity type opted into Phase 04 versioning.

Returns the stored boolean for opted-in entities; false for unregistered entities (defensive — callers might query before has_typed_eav runs in a particular load order). The Phase 04 transactional writer calls this only after its boot-latched callback has been installed; this lookup remains a small Hash#dig per write.

entities.dig(entity_type, :versioned) returns nil when entities[entity_type] is missing (no register call) OR when the entry is { types: ..., versioned: nil } (impossible by current register contract — kwarg default is false). The || false normalizes to a strict boolean so callers can if versioned?(...) without three-way logic.

Returns:

  • (Boolean)


80
81
82
# File 'lib/typed_eav/registry.rb', line 80

def versioned?(entity_type)
  entities.dig(entity_type, :versioned) || false
end