Module: Familia::Base

Included in:
DataType, Horreum
Defined in:
lib/familia/base.rb,
lib/familia/features/expiration/extensions.rb

Overview

Add a default update_expiration method for all classes that include Familia::Base. Since expiration is a core feature, we can confidently call horreum_instance.update_expiration without defensive programming even when expiration is not enabled for the horreum_instance class.

Defined Under Namespace

Modules: ClassMethods

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.feature_definitionsObject (readonly)

Returns the value of attribute feature_definitions.



112
113
114
# File 'lib/familia/base.rb', line 112

def feature_definitions
  @feature_definitions
end

.features_availableObject (readonly)

Returns the value of attribute features_available.



112
113
114
# File 'lib/familia/base.rb', line 112

def features_available
  @features_available
end

Class Method Details

.add_feature(klass, feature_name, depends_on: [], field_group: nil) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/familia/base.rb', line 114

def add_feature(klass, feature_name, depends_on: [], field_group: nil)
  @features_available ||= {}
  Familia.trace :ADD_FEATURE, klass, feature_name if Familia.debug?

  # Create field definition object
  feature_def = FeatureDefinition.new(
    name: feature_name,
    depends_on: depends_on,
    field_group: field_group
  )

  # Track field definitions after defining field methods
  @feature_definitions ||= {}
  @feature_definitions[feature_name] = feature_def

  features_available[feature_name] = klass
end

.find_feature(feature_name, starting_class = self) ⇒ Object

Find a feature by name, traversing the ancestry chain of classes that include Familia::Base



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/familia/base.rb', line 134

def find_feature(feature_name, starting_class = self)
  # Convert to symbol for consistent lookup
  feature_name = feature_name.to_sym

  # Walk up the ancestry chain, checking each class that includes Familia::Base
  starting_class.ancestors.each do |ancestor|
    next unless ancestor.respond_to?(:features_available)
    next unless ancestor.features_available

    return ancestor.features_available[feature_name] if ancestor.features_available.key?(feature_name)
  end

  nil
end

Instance Method Details

#as_json(options = nil) ⇒ Hash, Object

Prepares the object for JSON serialization by converting it to a hash. This method provides the data preparation step in the standard Ruby JSON pattern: to_json → as_json → JSON serialization.

Implementing classes can override this method to customize their JSON representation. For Horreum objects, this delegates to to_h which returns only the public fields. For DataType objects, this returns the raw value.

Parameters:

  • options (Hash) (defaults to: nil)

    Optional parameters for customizing JSON output

Returns:

  • (Hash, Object)

    JSON-serializable representation of the object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/familia/base.rb', line 78

def as_json(options = nil)
  if respond_to?(:to_h)
    # Horreum objects - return their field hash
    to_h
  elsif respond_to?(:members)
    # DataType objects (List, Set, etc.) - return their members
    members
  elsif respond_to?(:value)
    # String-like objects or simple values
    value
  else
    # Fallback for objects that don't have standard value methods
    # This ensures we don't expose internal state accidentally
    { class: self.class.name, id: respond_to?(:identifier) ? identifier : object_id }
  end
end

#expired?(_threshold = 0) ⇒ Boolean

Base implementation of expired? that returns false

Parameters:

  • _threshold (Numeric) (defaults to: 0)

    Ignored in base implementation

Returns:

  • (Boolean)

    Always returns false for the base implementation



57
58
59
# File 'lib/familia/features/expiration/extensions.rb', line 57

def expired?(_threshold = 0)
  false
end

#expires?Boolean

Base implementation of expires? that returns false

Returns:

  • (Boolean)

    Always returns false for the base implementation



48
49
50
# File 'lib/familia/features/expiration/extensions.rb', line 48

def expires?
  false
end

#generate_idObject



150
151
152
# File 'lib/familia/base.rb', line 150

def generate_id
  @identifier ||= Familia.generate_id
end

#to_json(options = nil) ⇒ String

Converts the object to a JSON string using Familia's JsonSerializer. This method completes the standard Ruby JSON pattern by calling as_json to prepare the data, then using JsonSerializer.dump for serialization.

This maintains security by ensuring all JSON serialization goes through Familia's controlled JsonSerializer (OJ in strict mode) rather than potentially unsafe serialization methods.

Parameters:

  • options (Hash) (defaults to: nil)

    Optional parameters passed to as_json

Returns:

  • (String)

    JSON string representation of the object



106
107
108
# File 'lib/familia/base.rb', line 106

def to_json(options = nil)
  Familia::JsonSerializer.dump(as_json(options))
end

#to_sString

Returns a string representation of the object. Implementing classes are welcome to override this method to provide a more meaningful representation. Using this as a default via super is recommended.

Returns:

  • (String)

    A string representation of the object. Never nil.



63
64
65
# File 'lib/familia/base.rb', line 63

def to_s
  "#<#{self.class}:0x#{object_id.to_s(16)}>"
end

#ttlInteger

Base implementation of ttl that returns -1 (no expiration set)

Returns:

  • (Integer)

    Always returns -1 for the base implementation



40
41
42
# File 'lib/familia/features/expiration/extensions.rb', line 40

def ttl
  -1
end

#update_expiration(expiration: nil) ⇒ nil

Note:

This is a no-op implementation. Classes that need expiration functionality should include the :expiration feature.

Base implementation of update_expiration that maintains API compatibility with the :expiration feature's implementation.

This is a no-op implementation that gets overridden by the :expiration feature when it is enabled. This allows for calling this method on any horreum model regardless of the feature status. It accepts an optional expiration parameter to maintain interface compatibility with the overriding implementations.

Examples:

MyModel.new.update_expiration(expiration: 3600) # => nothing happens

Parameters:

  • expiration (Numeric, nil) (defaults to: nil)

    Time To Live in seconds

Returns:

  • (nil)

    Always returns nil for the base implementation



28
29
30
31
32
33
34
# File 'lib/familia/features/expiration/extensions.rb', line 28

def update_expiration(expiration: nil)
  Familia.debug <<~LOG
    [update_expiration] Expiration feature not enabled for #{self.class}.
    Key: #{dbkey} Arg: #{expiration} (caller: #{caller(1..1)})
  LOG
  nil
end

#uuidObject



154
155
156
# File 'lib/familia/base.rb', line 154

def uuid
  @uuid ||= SecureRandom.uuid
end