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.



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

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

  entry[:types]
end

.entity_typesObject

All registered entity type names.



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

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 Phase 04 opt-in flag. When true, AND `Config.versioning = true` at engine load (gem-level master switch), the Phase 04 subscriber writes a TypedEAV::ValueVersion row per Value mutation on this entity_type. Default false — apps not using versioning pay zero cost (one Hash#dig per write at most when `Config.versioning = true`, nothing when off).

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.



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

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

.reset!Object

Clear all registrations (test isolation).



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

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)


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

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 subscriber calls this on every Value write when `Config.versioning = true` — performance is one Hash#dig per write, negligible.

‘entities.dig(entity_type, :versioned)` returns nil when `entities` 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)


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

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