module Sequent::Core::Helpers::AttributeSupport

Provides functionality for defining attributes with their types.

Since our Commands and ValueObjects are not backed by a database like e.g. Rails we can not infer their types. We need the types to be able to parse from and to json. You typically do not need to include this module in your classes. If you extend from Sequent::ValueObject, Sequent::Event or Sequent::Command you will get this functionality for free.

Example:

attrs name: String, age: Integer, born: Date

Currently Sequent supports the following types:

Public Class Methods

included(host_class) click to toggle source

extend host class with class methods when we’re included

# File lib/sequent/core/helpers/attribute_support.rb, line 164
def self.included(host_class)
  host_class.extend(ClassMethods)
  host_class.initialize_types
end

Public Instance Methods

as_json(opts = {}) click to toggle source
# File lib/sequent/core/helpers/attribute_support.rb, line 182
def as_json(opts = {})
  hash = HashWithIndifferentAccess.new
  self.class.types.each do |name, _|
    value = instance_variable_get("@#{name}")
    hash[name] = if value.respond_to?(:as_json)
                   value.as_json(opts)
                 else
                   value
                 end
  end
  hash
end
attributes() click to toggle source
# File lib/sequent/core/helpers/attribute_support.rb, line 169
def attributes
  hash = HashWithIndifferentAccess.new
  self.class.types.each do |name, _|
    value = instance_variable_get("@#{name}")
    hash[name] = if value.respond_to?(:attributes)
                   value.attributes
                 else
                   value
                 end
  end
  hash
end
ensure_known_attributes(attrs) click to toggle source
# File lib/sequent/core/helpers/attribute_support.rb, line 218
def ensure_known_attributes(attrs)
  return unless Sequent.configuration.strict_check_attributes_on_apply_events

  unknowns = attrs.keys.map(&:to_s) - self.class.types.keys.map(&:to_s)
  if unknowns.any?
    fail UnknownAttributeError, "#{self.class.name} does not specify attrs: #{unknowns.join(', ')}"
  end
end
update(changes) click to toggle source
# File lib/sequent/core/helpers/attribute_support.rb, line 195
def update(changes)
  self.class.new(attributes.merge(changes))
end
validation_errors(prefix = nil) click to toggle source
# File lib/sequent/core/helpers/attribute_support.rb, line 199
def validation_errors(prefix = nil)
  result = errors.to_hash
  self.class.types.each do |field|
    value = instance_variable_get("@#{field[0]}")
    if value.respond_to? :validation_errors
      value.validation_errors.each { |k, v| result["#{field[0]}_#{k}".to_sym] = v }
    elsif field[1].instance_of?(ArrayWithType) && value.present?
      value
        .select { |val| val.respond_to?(:validation_errors) }
        .each_with_index do |val, index|
          val.validation_errors.each do |k, v|
            result["#{field[0]}_#{index}_#{k}".to_sym] = v
          end
        end
    end
  end
  prefix ? HashWithIndifferentAccess[result.map { |k, v| ["#{prefix}_#{k}", v] }] : result
end