Module: Familia::Horreum::Serialization
- Included in:
- Familia::Horreum
- Defined in:
- lib/familia/horreum/serialization.rb
Overview
Serialization - Instance-level methods for object serialization Handles conversion between Ruby objects and Valkey hash storage
Instance Method Summary collapse
-
#deserialize_value(val, symbolize: true) ⇒ Object
Converts a Database string value back to its original Ruby type.
-
#serialize_value(val) ⇒ String?
Serializes a Ruby object for Valkey storage.
-
#to_a ⇒ Array
Converts the object's persistent fields to an array.
-
#to_h ⇒ Hash
Converts the object's persistent fields to a hash for external use.
-
#to_h_for_storage ⇒ Hash
Converts the object's persistent fields to a hash for database storage.
Instance Method Details
#deserialize_value(val, symbolize: true) ⇒ Object
Converts a Database string value back to its original Ruby type
This method attempts to deserialize JSON strings back to their original Hash or Array types. Simple string values are returned as-is.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/familia/horreum/serialization.rb', line 155 def deserialize_value(val, symbolize: true) return val if val.nil? || val == '' # Try to parse as JSON first for complex types begin parsed = Familia::JsonSerializer.parse(val, symbolize_names: symbolize) # Only return parsed value if it's a complex type (Hash/Array) # Simple values should remain as strings return parsed if parsed.is_a?(Hash) || parsed.is_a?(Array) rescue Familia::SerializerError # Not valid JSON, return as-is end val end |
#serialize_value(val) ⇒ String?
This method integrates with Familia's type system and supports custom serialization methods when available on the object
Serializes a Ruby object for Valkey storage.
Converts Ruby objects into the DB-compatible string representations using the Familia distinguisher for type coercion. Falls back to JSON serialization for complex types (Hash, Array) when the primary distinguisher returns nil.
The serialization process:
- Attempts conversion using Familia.distinguisher with relaxed type checking
- For Hash/Array types that return nil, tries custom dump_method or Familia::JsonSerializer.dump
- Logs warnings when serialization fails completely
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/familia/horreum/serialization.rb', line 128 def serialize_value(val) # Security: Handle ConcealedString safely - extract encrypted data for storage return val.encrypted_value if val.respond_to?(:encrypted_value) prepared = Familia.distinguisher(val, strict_values: false) # If the distinguisher returns nil, try using the dump_method but only # use JSON serialization for complex types that need it. if prepared.nil? && (val.is_a?(Hash) || val.is_a?(Array)) prepared = val.respond_to?(dump_method) ? val.send(dump_method) : Familia::JsonSerializer.dump(val) end # If both the distinguisher and dump_method return nil, log an error Familia.ld "[#{self.class}#serialize_value] nil returned for #{self.class}" if prepared.nil? prepared end |
#to_a ⇒ Array
Values are serialized using the same process as other persistence methods to maintain data consistency across operations.
Converts the object's persistent fields to an array.
Serializes all persistent field values in field definition order, preparing them for Valkey storage. Each value is processed through the serialization pipeline to ensure Valkey compatibility.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/familia/horreum/serialization.rb', line 86 def to_a self.class.persistent_fields.filter_map do |field| field_type = self.class.field_types[field] # Security: Skip non-loggable fields (e.g., encrypted fields) next unless field_type.loggable method_name = field_type.method_name val = send(method_name) prepared = serialize_value(val) Familia.ld " [to_a] field: #{field} method: #{method_name} val: #{val.class} prepared: #{prepared.class}" prepared end end |
#to_h ⇒ Hash
Only loggable fields are included for security
Only fields with non-nil values are included
Converts the object's persistent fields to a hash for external use.
Serializes persistent field values for external consumption (APIs, logs), excluding non-loggable fields like encrypted fields for security. Only non-nil values are included in the resulting hash.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/familia/horreum/serialization.rb', line 26 def to_h self.class.persistent_fields.each_with_object({}) do |field, hsh| field_type = self.class.field_types[field] # Security: Skip non-loggable fields (e.g., encrypted fields) next unless field_type.loggable method_name = field_type.method_name val = send(method_name) prepared = serialize_value(val) Familia.ld " [to_h] field: #{field} val: #{val.class} prepared: #{prepared&.class || '[nil]'}" # Only include non-nil values in the hash for Valkey # Use string key for database compatibility hsh[field.to_s] = prepared unless prepared.nil? end end |
#to_h_for_storage ⇒ Hash
Includes ALL persistent fields, including encrypted fields
Only fields with non-nil values are included for storage efficiency
Converts the object's persistent fields to a hash for database storage.
Serializes ALL persistent field values for database storage, including encrypted fields. This is used internally by commit_fields and other persistence operations.
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/familia/horreum/serialization.rb', line 56 def to_h_for_storage self.class.persistent_fields.each_with_object({}) do |field, hsh| field_type = self.class.field_types[field] method_name = field_type.method_name val = send(method_name) prepared = serialize_value(val) Familia.ld " [to_h_for_storage] field: #{field} val: #{val.class} prepared: #{prepared&.class || '[nil]'}" # Only include non-nil values in the hash for Valkey # Use string key for database compatibility hsh[field.to_s] = prepared unless prepared.nil? end end |