Class: Familia::Features::ObjectIdentifier::ObjectIdentifierFieldType
- Inherits:
-
Familia::FieldType
- Object
- Familia::FieldType
- Familia::Features::ObjectIdentifier::ObjectIdentifierFieldType
- Defined in:
- lib/familia/features/object_identifier.rb
Overview
ObjectIdentifierFieldType - Generate a unique object identifier
Object identifier fields automatically generate unique identifiers when first accessed if not already set. The generation strategy is configurable via feature options. These fields preserve any values set during initialization to ensure data integrity when loading existing objects from the database.
The field type tracks the generator used for each objid to provide provenance information for security-sensitive operations like external identifier generation. This ensures that downstream features can validate the source and format of object identifiers without relying on string pattern matching, which cannot reliably distinguish between uuid7, uuid4, or hex formats in all cases.
Instance Method Summary collapse
-
#category ⇒ Symbol
Category for object identifier fields.
-
#define_getter(klass) ⇒ Object
Override getter to provide lazy generation with configured strategy.
-
#define_setter(klass) ⇒ Object
Override setter to preserve values during initialization.
-
#persistent? ⇒ Boolean
Object identifier fields are persisted to database.
Constructor Details
This class inherits a constructor from Familia::FieldType
Instance Method Details
#category ⇒ Symbol
Category for object identifier fields
222 223 224 |
# File 'lib/familia/features/object_identifier.rb', line 222 def category :object_identifier end |
#define_getter(klass) ⇒ Object
Override getter to provide lazy generation with configured strategy
Generates the identifier using the configured strategy if not already set. This preserves any values set during initialization while providing automatic generation for new objects.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/familia/features/object_identifier.rb', line 147 def define_getter(klass) field_name = @name method_name = @method_name handle_method_conflict(klass, method_name) do klass.define_method method_name do # Check if we already have a value (from initialization or previous generation) existing_value = instance_variable_get(:"@#{field_name}") return existing_value unless existing_value.nil? # Generate new identifier using configured strategy generated_id = generate_object_identifier instance_variable_set(:"@#{field_name}", generated_id) # Track which generator was used for provenance = self.class.(:object_identifier) generator = [:generator] || DEFAULT_GENERATOR instance_variable_set(:"@#{field_name}_generator_used", generator) generated_id end end # Define getter for generator provenance tracking handle_method_conflict(klass, :"#{method_name}_generator_used") do klass.define_method :"#{method_name}_generator_used" do instance_variable_get(:"@#{field_name}_generator_used") end end end |
#define_setter(klass) ⇒ Object
Override setter to preserve values during initialization
This ensures that values passed during object initialization (e.g., when loading from Valkey/Redis) are preserved and not overwritten by the lazy generation logic.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/familia/features/object_identifier.rb', line 186 def define_setter(klass) field_name = @name method_name = @method_name handle_method_conflict(klass, :"#{method_name}=") do klass.define_method :"#{method_name}=" do |value| # Remove old mapping if objid is changing old_value = instance_variable_get(:"@#{field_name}") if old_value && old_value != value Familia.logger.info("Removing objid mapping for #{old_value}") self.class.objid_lookup.remove_field(old_value) end instance_variable_set(:"@#{field_name}", value) # When setting objid from external source (e.g., loading from Valkey/Redis), # infer the generator type from the format to restore provenance tracking. # This allows features like ExternalIdentifier to work correctly on loaded objects. inferred_generator = infer_objid_generator(value) instance_variable_set(:"@#{field_name}_generator_used", inferred_generator) end end end |
#persistent? ⇒ Boolean
Object identifier fields are persisted to database
214 215 216 |
# File 'lib/familia/features/object_identifier.rb', line 214 def persistent? true end |