lib/ecoportal/api/common/base_model.rb in ecoportal-api-0.9.7 vs lib/ecoportal/api/common/base_model.rb in ecoportal-api-0.10.0
- old
+ new
@@ -1,13 +1,14 @@
+# rubocop:disable Naming/PredicateName
module Ecoportal
module API
module Common
class BaseModel
- class UnlinkedModel < Exception
- def initialize (msg = "Something went wrong when linking the document.", from: nil, key: nil)
- msg += " From: #{from}." if from
- msg += " key: #{key}." if key
+ class UnlinkedModel < StandardError
+ def initialize(msg = "Something went wrong when linking the document.", from: nil, key: nil)
+ msg << " From: #{from}." if from
+ msg << " key: #{key}." if key
super(msg)
end
end
extend BaseClass
@@ -23,75 +24,83 @@
send(to)[method] = value
end
end
end
- def embeds_one(method, key: method, nullable: false, klass:)
+ def embeds_one(method, klass:, key: method, nullable: false)
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
-
end
attr_reader :_parent, :_key
def initialize(doc = {}, parent: self, key: nil)
@_parent = parent
@_key = key
- if !_parent || !_key
- @doc = JSON.parse(doc.to_json)
- @original_doc = JSON.parse(@doc.to_json)
- @initial_doc = JSON.parse(@doc.to_json)
- end
+
+ return unless !_parent || !_key
+
+ @doc = JSON.parse(doc.to_json)
+ @original_doc = JSON.parse(@doc.to_json)
+ @initial_doc = JSON.parse(@doc.to_json)
end
def doc
- raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
+ raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
return @doc if is_root?
+
_parent.doc.dig(*[_key].flatten)
end
def original_doc
- raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked?
+ 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
def initial_doc
- raise UnlinkedModel.new(from: "#{self.class}#initial_doc", key: _key) unless linked?
+ 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
# It replaces `doc` by `new_doc`
# @return [Hash] `doc` before change
def replace_doc!(new_doc)
raise UnlinkedModel.new(from: "#{self.class}#replace_doc", key: _key) unless linked?
+
@doc.tap do
@doc = new_doc
end
end
# It replaces `original_doc` by `new_doc`
# @return [Hash] `original_doc` before change
def replace_original_doc!(new_doc)
raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
+
@original_doc.tap do
@original_doc = new_doc
end
end
@@ -113,11 +122,12 @@
as_update != {}
end
# It consolidates all the changes carried by `doc` by setting it as `original_doc`.
def consolidate!
- raise UnlinkedModel.new(from: "#{self.class}#consolidate!", key: _key) unless linked?
+ 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)
@@ -128,22 +138,23 @@
# @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
- 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?
+ def reset!(key = nil) # rubocop:disable Metrics/AbcSize>
+ msg = "'key' should be a String. Given #{key}"
+ raise ArgumentError, msg 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)
+ if respond_to?(key) && (child = 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)
+ send(key) if !new_doc && respond_to?(key)
end
else
new_doc = JSON.parse(original_doc.to_json)
if is_root?
@doc = new_doc
@@ -177,19 +188,19 @@
dig_set(obj[keys.first], keys.slice(1..-1), value)
end
end
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]) || []
+ msg = "#{key}= needs to be passed an Array, got #{value.class}"
+ raise ArgumentError, msg unless value.is_a?(Array)
+ 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
-
end
end
end
end
+
+# rubocop:enable Naming/PredicateName