Module: Sequent::Core::Helpers::AttributeSupport

Included in:
BaseCommand, Event, ValueObject
Defined in:
lib/sequent/core/helpers/attribute_support.rb

Overview

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:

  • String

  • Integer

  • Boolean

  • Date

  • DateTime

  • Subclasses of Sequent::ValueObject

  • Lists defined as ‘array(String)`

  • BigDecimal

  • Sequent::Secret

Defined Under Namespace

Modules: ClassMethods Classes: UnknownAttributeError

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(host_class) ⇒ Object

extend host class with class methods when we’re included



139
140
141
# File 'lib/sequent/core/helpers/attribute_support.rb', line 139

def self.included(host_class)
  host_class.extend(ClassMethods)
end

Instance Method Details

#as_json(opts = {}) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/sequent/core/helpers/attribute_support.rb', line 156

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

#attributesObject



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/sequent/core/helpers/attribute_support.rb', line 143

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) ⇒ Object



192
193
194
195
196
197
198
199
# File 'lib/sequent/core/helpers/attribute_support.rb', line 192

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) ⇒ Object



169
170
171
# File 'lib/sequent/core/helpers/attribute_support.rb', line 169

def update(changes)
  self.class.new(attributes.merge(changes))
end

#validation_errors(prefix = nil) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/sequent/core/helpers/attribute_support.rb', line 173

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