Module: StructuredStore::Storable

Extended by:
ActiveSupport::Concern
Defined in:
app/models/concerns/structured_store/storable.rb

Overview

This module is included in models that need to be stored in a structured way. It provides the necessary methods and attributes for structured storage.

To use this module, include it in your model and call ‘structured_store` for each store column you want to configure. Each call will create a belongs_to association to a VersionedSchema and define helper methods for accessing the JSON schema.

Examples:

Basic usage

class User < ApplicationRecord
  include StructuredStore::Storable

  structured_store :preferences
  structured_store :metadata
end

Custom schema name

class Product < ApplicationRecord
  include StructuredStore::Storable

  structured_store :configuration, schema_name: 'product_config_schema'
end

Instance Method Summary collapse

Instance Method Details

#define_all_store_accessors!Object

Define accessors for all configured store columns



125
126
127
128
129
# File 'app/models/concerns/structured_store/storable.rb', line 125

def define_all_store_accessors!
  _structured_store_configurations.each do |config|
    define_store_accessors_for_column(config[:column_name])
  end
end

#define_store_accessors_for_column(column_name) ⇒ Object

Dynamically define accessors for the properties defined in the JSON schema for this specific store column.

This method is run automatically as an ‘after_initialize` callback, but can be called at any time for debugging and testing purposes.

It skips defining the accessors if there is insufficient information to do so.

Parameters:

  • column_name (String)

    The name of the store column



140
141
142
143
144
145
146
147
148
# File 'app/models/concerns/structured_store/storable.rb', line 140

def define_store_accessors_for_column(column_name)
  return unless sufficient_info_to_define_store_accessors?(column_name)

  singleton_class.store_accessor(column_name.to_sym, json_schema_properties(column_name).keys)

  property_resolvers(column_name).each_value do |resolver|
    resolver.define_attribute.call(self)
  end
end

#initialize(attributes = nil) ⇒ Object

Override initialize to handle store attributes after accessors are defined



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/models/concerns/structured_store/storable.rb', line 33

def initialize(attributes = nil)
  unless attributes.is_a?(Hash)
    super
    return
  end

  # Separate known from unknown attributes and call super, then re-assign
  known_attrs, unknown_attrs = separate_known_and_unknown_attributes(attributes)

  super(known_attrs)

  assign_attributes(unknown_attrs) if unknown_attrs.present?
end

#property_resolvers(column_name) ⇒ Hash<String, StructuredStore::RefResolvers::Base>

Returns an array of property resolvers for each property in the JSON schema. The resolvers are responsible for handling references and defining attributes for each property defined in the schema.

Parameters:

  • column_name (String)

    The name of the store column

Returns:



156
157
158
159
160
161
162
163
164
# File 'app/models/concerns/structured_store/storable.rb', line 156

def property_resolvers(column_name)
  return {} if column_name.nil?

  @property_resolvers ||= {}
  @property_resolvers[column_name] ||= json_schema_properties(column_name).keys.index_with do |property_name|
    StructuredStore::RefResolvers::Registry.matching_resolver(schema_inspector(column_name),
                                                              property_name)
  end
end