Module: ORMivore::Entity::ClassMethods

Defined in:
lib/ormivore/entity.rb

Constant Summary collapse

ALLOWED_ATTRIBUTE_TYPES =
[String, Symbol, Integer, Float].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#attributes_declarationObject (readonly)

Returns the value of attribute attributes_declaration.



7
8
9
# File 'lib/ormivore/entity.rb', line 7

def attributes_declaration
  @attributes_declaration
end

#optional_attributes_listObject (readonly)

Returns the value of attribute optional_attributes_list.



8
9
10
# File 'lib/ormivore/entity.rb', line 8

def optional_attributes_list
  @optional_attributes_list
end

Instance Method Details

#attributes_listObject



10
11
12
# File 'lib/ormivore/entity.rb', line 10

def attributes_list
  attributes_declaration.keys
end

#coerce(attrs) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ormivore/entity.rb', line 55

def coerce(attrs)
  attrs.each do |name, type|
    attr_value = attrs[name]
    declared_type = attributes_declaration[name]
    if declared_type && !attr_value.is_a?(declared_type)
      attrs[name] = Kernel.public_send(declared_type.name.to_sym, attr_value)
    end
  end
rescue ArgumentError => e
  raise ORMivore::BadArgumentError.new(e)
end

#construct(attrs, id) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/ormivore/entity.rb', line 14

def construct(attrs, id)
  id = coerce_id(id)

  coerced_attrs = attrs.symbolize_keys.tap { |h| coerce(h) }.freeze

  base_attributes = coerced_attrs
  dirty_attributes = {}.freeze

  validate_presence_of_proper_attributes(base_attributes, dirty_attributes)

  obj = allocate

  obj.instance_variable_set(:@id, id)
  obj.instance_variable_set(:@base_attributes, base_attributes)
  obj.instance_variable_set(:@dirty_attributes, dirty_attributes)

  # TODO how to do custom validation?
  # validate

  obj
end

#validate_presence_of_proper_attributes(base, dirty) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ormivore/entity.rb', line 36

def validate_presence_of_proper_attributes(base, dirty)
  # doing complicated way first because it is much more memory efficient
  # but it does not allow for good error messages, so if something is
  # wrong, need to proceed to inefficient validation that produces nice
  # messages
  missing = 0
  known_counts = attributes_list.each_with_object([0, 0]) { |attr, acc|
    acc[0] += 1 if base[attr]
    acc[1] += 1 if dirty[attr]
    missing +=1 unless optional_attributes_list.include?(attr) || base[attr] || dirty[attr]
  }

  if missing > 0 || [base.length, dirty.length] != known_counts
    expensive_validate_presence_of_proper_attributes(
      base.merge(dirty)
    )
  end
end