class Ecoportal::API::Common::BaseModel
Attributes
_key[R]
_parent[R]
Public Class Methods
embeds_one(method, key: method, nullable: false, klass:)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 28 def embeds_one(method, key: method, nullable: false, klass:) method = method.to_s.freeze var = "@#{method}".freeze key = key.to_s.freeze define_method(method) do if instance_variable_defined?(var) value = instance_variable_get(var) return value unless nullable return value if (value && doc[key]) || (!value && !doc[key]) remove_instance_variable(var) end doc[key] ||= {} unless nullable return instance_variable_set(var, nil) unless doc[key] self.class.resolve_class(klass).new( doc[key], parent: self, key: key ).tap {|obj| instance_variable_set(var, obj)} end end
new(doc = {}, parent: self, key: nil)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 52 def initialize(doc = {}, parent: self, key: nil) @_parent = parent @_key = key if !_parent || !_key @doc = doc @original_doc = JSON.parse(@doc.to_json) @initial_doc = JSON.parse(@doc.to_json) end end
passthrough(*methods, to: :doc)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 16 def passthrough(*methods, to: :doc) methods.each do |method| method = method.to_s define_method method do send(to)[method] end define_method "#{method}=" do |value| send(to)[method] = value end end end
Public Instance Methods
as_json()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 80 def as_json doc end
as_update(ref = :last, ignore: [])
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 88 def as_update(ref = :last, ignore: []) new_doc = as_json ref_doc = ref == :total ? initial_doc : original_doc Common::HashDiff.diff(new_doc, ref_doc, ignore: ignore) end
consolidate!()
click to toggle source
It consolidates all the changes carried by `doc` by setting it as `original_doc`.
# File lib/ecoportal/api/common/base_model.rb, line 99 def consolidate! raise UnlinkedModel.new(from: "#{self.class}#consolidate!", key: _key) unless linked? new_doc = JSON.parse(doc.to_json) if is_root? @original_doc = new_doc else dig_set(_parent.original_doc, [_key].flatten, new_doc) end end
dirty?()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 94 def dirty? as_update != {} end
doc()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 62 def doc raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked? return @doc if is_root? _parent.doc.dig(*[_key].flatten) end
initial_doc()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 74 def initial_doc raise UnlinkedModel.new(from: "#{self.class}#initial_doc", key: _key) unless linked? return @initial_doc if is_root? _parent.initial_doc.dig(*[_key].flatten) end
original_doc()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 68 def original_doc raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked? return @original_doc if is_root? _parent.original_doc.dig(*[_key].flatten) end
print_pretty()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 138 def print_pretty puts JSON.pretty_generate(as_json) self end
reset!(key = nil)
click to toggle source
It removes all the changes carried by `doc` by restoring `original_doc` into `doc`. @note
1. When there are nullable properties, it may be required to apply `reset!` from the parent i.e. `parent.reset!("child")` # when parent.child is `nil` 2. In such a case, only immediate childs are allowed to be reset
@param key [String, Array<String>, nil] if given, it only resets the specified property
# File lib/ecoportal/api/common/base_model.rb, line 115 def reset!(key = nil) raise "'key' should be a String. Given #{key}" unless !key || key.is_a?(String) raise UnlinkedModel.new(from: "#{self.class}#reset!", key: _key) unless linked? if key if self.respond_to?(key) && child = self.send(key) && child.is_a?(Ecoportal::API::Common::BaseModel) child.reset! else new_doc = original_doc && original_doc[key] dig_set(doc, [key], new_doc && JSON.parse(new_doc.to_json)) # regenerate object if new_doc is null self.send(key) if !new_doc && self.respond_to?(key) end else new_doc = JSON.parse(original_doc.to_json) if is_root? @doc = new_doc else dig_set(_parent.doc, [_key].flatten, new_doc) end end end
to_json(*args)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 84 def to_json(*args) doc.to_json(*args) end
Protected Instance Methods
is_root?()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 145 def is_root? _parent == self && !!defined?(@doc) end
linked?()
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 149 def linked? is_root? || !!_parent.doc.dig(*[_key].flatten) end
Private Instance Methods
dig_set(obj, keys, value)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 155 def dig_set(obj, keys, value) if keys.length == 1 obj[keys.first] = value else dig_set(obj[keys.first], keys.slice(1..-1), value) end end
set_uniq_array_keep_order(key, value)
click to toggle source
# File lib/ecoportal/api/common/base_model.rb, line 163 def set_uniq_array_keep_order(key, value) unless value.is_a?(Array) raise "#{key}= needs to be passed an Array, got #{value.class}" end ini_vals = (original_doc && original_doc[key]) || [] value = value.uniq # preserve original order to avoid false updates doc[key] = ((ini_vals & value) + (value - ini_vals)).compact end