Class: ROM::Factory::TupleEvaluator Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rom/factory/tuple_evaluator.rb

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Defined Under Namespace

Classes: TupleEvaluatorError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes, relation, traits = {}) ⇒ TupleEvaluator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of TupleEvaluator.



45
46
47
48
49
50
# File 'lib/rom/factory/tuple_evaluator.rb', line 45

def initialize(attributes, relation, traits = {})
  @attributes = attributes
  @relation = relation.with(auto_struct: true)
  @traits = traits
  @sequence = Sequences[relation]
end

Instance Attribute Details

#attributesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



33
34
35
# File 'lib/rom/factory/tuple_evaluator.rb', line 33

def attributes
  @attributes
end

#relationObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



36
37
38
# File 'lib/rom/factory/tuple_evaluator.rb', line 36

def relation
  @relation
end

#sequenceObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



42
43
44
# File 'lib/rom/factory/tuple_evaluator.rb', line 42

def sequence
  @sequence
end

#traitsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



39
40
41
# File 'lib/rom/factory/tuple_evaluator.rb', line 39

def traits
  @traits
end

Instance Method Details

#assoc_names(traits = []) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



117
118
119
# File 'lib/rom/factory/tuple_evaluator.rb', line 117

def assoc_names(traits = [])
  assocs(traits).map(&:name)
end

#assocs(traits_names = []) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/rom/factory/tuple_evaluator.rb', line 121

def assocs(traits_names = [])
  found_assocs = traits
    .values_at(*traits_names)
    .compact
    .map(&:associations).flat_map(&:elements)
    .inject(AttributeRegistry.new(attributes.associations.elements), :<<)

  exclude = traits_names.select { |t| t.is_a?(Hash) }.reduce(:merge) || EMPTY_HASH

  found_assocs.reject { |a| exclude[a.name] == false }
end

#build_assoc?(name, attributes) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


96
97
98
# File 'lib/rom/factory/tuple_evaluator.rb', line 96

def build_assoc?(name, attributes)
  attributes.key?(name) && attributes[name] != [] && !attributes[name].nil?
end

#build_assoc_attrs(key, fk, value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



100
101
102
103
104
105
106
# File 'lib/rom/factory/tuple_evaluator.rb', line 100

def build_assoc_attrs(key, fk, value)
  if value.is_a?(Array)
    value.map { |el| build_assoc_attrs(key, fk, el) }
  else
    {attributes[key].foreign_key => fk}.merge(value.to_h)
  end
end

#defaults(traits, attrs, **opts) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



57
58
59
60
# File 'lib/rom/factory/tuple_evaluator.rb', line 57

def defaults(traits, attrs, **opts)
  mergeable_attrs = select_mergeable_attrs(traits, attrs)
  evaluate(traits, attrs, opts).merge(mergeable_attrs)
end

#has_associations?(traits = []) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


134
135
136
# File 'lib/rom/factory/tuple_evaluator.rb', line 134

def has_associations?(traits = [])
  !assoc_names(traits).empty?
end

#model(traits, combine: assoc_names(traits)) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



52
53
54
# File 'lib/rom/factory/tuple_evaluator.rb', line 52

def model(traits, combine: assoc_names(traits))
  @relation.combine(*combine).mapper.model
end

#persist_associations(tuple, parent, traits = []) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



109
110
111
112
113
114
# File 'lib/rom/factory/tuple_evaluator.rb', line 109

def persist_associations(tuple, parent, traits = [])
  assoc_names(traits).each do |name|
    assoc = tuple[name]
    assoc.call(parent, persist: true) if assoc.is_a?(Proc)
  end
end

#primary_keyObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



139
140
141
# File 'lib/rom/factory/tuple_evaluator.rb', line 139

def primary_key
  relation.primary_key
end

#struct(*traits, **attrs) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rom/factory/tuple_evaluator.rb', line 63

def struct(*traits, **attrs)
  merged_attrs = struct_attrs.merge(defaults(traits, attrs, persist: false))
  is_callable = proc { |_name, value| value.respond_to?(:call) }

  callables = merged_attrs.select(&is_callable)
  attributes = merged_attrs.reject(&is_callable)

  materialized_callables = {}
  callables.each_value do |callable|
    materialized_callables.merge!(callable.call(attributes, persist: false))
  end

  attributes.merge!(materialized_callables)

  assoc_attrs = attributes.slice(*assoc_names(traits)).merge(
    assoc_names(traits)
      .select { |key|
        build_assoc?(key, attributes)
      }
      .map { |key|
        [key, build_assoc_attrs(key, attributes[relation.primary_key], attributes[key])]
      }
    .to_h
  )

  model_attrs = relation.output_schema[attributes]
  model_attrs.update(assoc_attrs)

  model(traits).new(**model_attrs)
rescue StandardError => e
  raise TupleEvaluatorError.new(relation, e, attrs, traits, assoc_attrs)
end