module SchemaModel::InstanceMethods

Attributes

changed_attributes[RW]

Public Class Methods

new(attrs = {}) click to toggle source
# File lib/utils/schema_model.rb, line 66
def initialize(attrs = {})
  attrs.each do |attr, v|
    send("#{attr}=", v)
  end
end

Public Instance Methods

errors() click to toggle source
# File lib/utils/schema_model.rb, line 72
def errors
  check definition, self
end
to_json() click to toggle source
# File lib/utils/schema_model.rb, line 80
def to_json
  return nil unless changed_attributes
  Hash[
    changed_attributes.map { |attr| serialize_attr(attr) }
  ]
end
valid?() click to toggle source
# File lib/utils/schema_model.rb, line 76
def valid?
  errors.empty?
end

Private Instance Methods

append!(errors, attr, key, val) click to toggle source

Mutates errors, adding in error messages scoped to the attribute and key @param [Maybe Hash] errors - @param [Symbol] attr - name of attribute under check @param [Symbol] key - name of validation step @param [Object] val - data to append

# File lib/utils/schema_model.rb, line 151
def append!(errors, attr, key, val)
  return unless val.present?

  errors ||= {}
  errors[attr] ||= {}
  errors[attr][key] = val
end
check(schema, data) click to toggle source

@param [Hash] schema @param [Hash|Object] data @return [Hash]

# File lib/utils/schema_model.rb, line 162
def check(schema, data)
  schema.reduce({}) do |errors, (attr, defn)|
    # Destructuring
    child_schema, type = defn.values_at :schema, :type

    # Get the value for this attribute
    value = data.send attr

    # Add error messages
    append! errors, attr, :child, check_children(child_schema, value)
    append! errors, attr, :type, check_type(type, value)
    errors
  end
end
check_children(child_schema, value) click to toggle source

Given a schema and a value which may be a single record or collection, collect and return any errors. @param [SchemaModel] child_schema - A schema object class @param [Object] value - Array of models or single model @return [Object] Array of errors hashes, or one hash.

Structure matches 'value' input
# File lib/utils/schema_model.rb, line 110
def check_children(child_schema, value)
  return unless child_schema && value.present?

  if value.is_a? Array
    value.map(&:errors).reject(&:empty?)
  else
    value.errors
  end
end
check_type(type, value) click to toggle source

Checks that value is of correct type @param [Maybe Class] type - type to check using value.is_a?(type) @param [Object] value - value to check @return [Maybe String] error message

# File lib/utils/schema_model.rb, line 124
def check_type(type, value)
  return unless type && value && !value.is_a?(type)

  "should be of type #{type} but is of type #{value.class}"
end
check_validation(valid, value) click to toggle source

Checks that required field meets validation @param [Boolean or Callable] valid - callable validation fn or boolean

function will be called with value

@param [Object] value - value to check @return [Maybe String] error message

# File lib/utils/schema_model.rb, line 135
def check_validation(valid, value)
  return unless valid && value

  passes_validation = begin
                        valid.call(value)
                      rescue StandardError
                        false
                      end
  passes_validation ? nil : 'is invalid'
end
ensure_schema(value, child_schema) click to toggle source

Constructs new instance(s) of provided Schema model from hash or array of hash values. Allows for modeling of has_one and has_many. @param [Array of Hashes or SchemaModels] value @param [SchemaModel] child_schema

# File lib/utils/schema_model.rb, line 182
def ensure_schema(value, child_schema)
  if value.present? && child_schema.present?
    value = if child_schema.is_a?(Array)
              value.map do |item|
                item.is_a?(SchemaModel) ? item : child_schema[0].new(item)
              end
            else
              value.is_a?(SchemaModel) ? value : child_schema.new(value)
            end
  end

  value
end
serialize_attr(attr) click to toggle source

@param [Symbol] attr @return [Array]

# File lib/utils/schema_model.rb, line 91
def serialize_attr(attr)
  value = send(attr)
  value = if value.is_a?(Hash) || value.is_a?(SchemaModel)
            value.to_json
          elsif value.is_a?(Array)
            value.map(&:to_json)
          else
            value
          end

  [attr.to_s.camelize(:lower), value]
end