ecoportal-api-v2 2.0.16 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -1
- data/ecoportal-api-v2.gemspec +1 -1
- data/lib/ecoportal/api/common/concerns.rb +2 -2
- data/lib/ecoportal/api/common/content/class_helpers.rb +42 -7
- data/lib/ecoportal/api/common/content/client.rb +2 -1
- data/lib/ecoportal/api/common/content/collection_model/doc/rooted_key.rb +8 -8
- data/lib/ecoportal/api/common/content/collection_model/doc.rb +2 -2
- data/lib/ecoportal/api/common/content/collection_model/doc_mutation.rb +3 -3
- data/lib/ecoportal/api/common/content/collection_model/model.rb +6 -6
- data/lib/ecoportal/api/common/content/collection_model/modifiers.rb +3 -3
- data/lib/ecoportal/api/common/content/collection_model/mutation.rb +3 -3
- data/lib/ecoportal/api/common/content/collection_model.rb +5 -5
- data/lib/ecoportal/api/common/content/double_model/attributable/nesting/cascaded_callback.rb +203 -98
- data/lib/ecoportal/api/common/content/double_model/attributable/nesting/embeddable.rb +49 -59
- data/lib/ecoportal/api/common/content/double_model/attributable/nesting/keyable.rb +102 -114
- data/lib/ecoportal/api/common/content/double_model/attributable/nesting.rb +5 -3
- data/lib/ecoportal/api/common/content/double_model/attributable.rb +5 -5
- data/lib/ecoportal/api/common/content/double_model/diffable/diff_service.rb +33 -0
- data/lib/ecoportal/api/common/content/double_model/{diffable_model.rb → diffable.rb} +12 -5
- data/lib/ecoportal/api/common/content/double_model/double_doc/linkable_doc.rb +9 -4
- data/lib/ecoportal/api/common/content/double_model/double_doc/replaceable_doc.rb +10 -2
- data/lib/ecoportal/api/common/content/double_model/double_doc/reset_consolidate.rb +1 -1
- data/lib/ecoportal/api/common/content/double_model/double_doc/rooted_key.rb +10 -3
- data/lib/ecoportal/api/common/content/double_model/double_doc.rb +5 -5
- data/lib/ecoportal/api/common/content/double_model/hash_helpers.rb +23 -4
- data/lib/ecoportal/api/common/content/double_model/modifiers.rb +2 -2
- data/lib/ecoportal/api/common/content/double_model.rb +9 -9
- data/lib/ecoportal/api/common/content/hash_diff_patch.rb +21 -7
- data/lib/ecoportal/api/common/content/model_helpers.rb +1 -1
- data/lib/ecoportal/api/common/content.rb +11 -11
- data/lib/ecoportal/api/common.v2.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/action.rb +13 -11
- data/lib/ecoportal/api/v2/page/component/action_field.rb +14 -12
- data/lib/ecoportal/api/v2/page/component/actions_field.rb +2 -1
- data/lib/ecoportal/api/v2/page/component/chart_field/config.rb +1 -2
- data/lib/ecoportal/api/v2/page/component/chart_field.rb +48 -44
- data/lib/ecoportal/api/v2/page/component/chart_fr_field.rb +0 -1
- data/lib/ecoportal/api/v2/page/component/checklist_field.rb +9 -6
- data/lib/ecoportal/api/v2/page/component/checklist_item.rb +2 -3
- data/lib/ecoportal/api/v2/page/component/contractor_entities_field.rb +18 -17
- data/lib/ecoportal/api/v2/page/component/date_field.rb +19 -18
- data/lib/ecoportal/api/v2/page/component/file.rb +3 -3
- data/lib/ecoportal/api/v2/page/component/files_field.rb +9 -6
- data/lib/ecoportal/api/v2/page/component/gauge_field.rb +3 -2
- data/lib/ecoportal/api/v2/page/component/gauge_stop.rb +26 -26
- data/lib/ecoportal/api/v2/page/component/geo_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/image.rb +6 -5
- data/lib/ecoportal/api/v2/page/component/images_field.rb +21 -20
- data/lib/ecoportal/api/v2/page/component/law.rb +3 -4
- data/lib/ecoportal/api/v2/page/component/law_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/number_field.rb +1 -1
- data/lib/ecoportal/api/v2/page/component/people_field.rb +19 -19
- data/lib/ecoportal/api/v2/page/component/plain_text_field.rb +6 -7
- data/lib/ecoportal/api/v2/page/component/reference_field.rb +1 -1
- data/lib/ecoportal/api/v2/page/component/rich_text_field.rb +3 -3
- data/lib/ecoportal/api/v2/page/component/selection_field.rb +32 -35
- data/lib/ecoportal/api/v2/page/component/selection_options.rb +12 -7
- data/lib/ecoportal/api/v2/page/component/tag_field.rb +5 -4
- data/lib/ecoportal/api/v2/page/component.rb +21 -21
- data/lib/ecoportal/api/v2/page/force/bindings.rb +49 -39
- data/lib/ecoportal/api/v2/page/force.rb +9 -9
- data/lib/ecoportal/api/v2/page/forces.rb +1 -1
- data/lib/ecoportal/api/v2/page/permit.rb +3 -3
- data/lib/ecoportal/api/v2/page/sections.rb +19 -14
- data/lib/ecoportal/api/v2/page/stage.rb +27 -20
- data/lib/ecoportal/api/v2/page/stages.rb +1 -1
- data/lib/ecoportal/api/v2/page.rb +13 -12
- data/lib/ecoportal/api/v2/pages/page_stage.rb +2 -2
- data/lib/ecoportal/api/v2/pages.rb +2 -2
- data/lib/ecoportal/api/v2/registers/page_result.rb +3 -3
- data/lib/ecoportal/api/v2/registers/register.rb +4 -5
- data/lib/ecoportal/api/v2/registers/search_results.rb +1 -1
- data/lib/ecoportal/api/v2/registers/stages_result.rb +1 -1
- data/lib/ecoportal/api/v2/registers.rb +6 -6
- data/lib/ecoportal/api/v2/s3/files/batch_upload.rb +1 -0
- data/lib/ecoportal/api/v2/s3/files.rb +3 -3
- data/lib/ecoportal/api/v2.rb +4 -4
- data/lib/ecoportal/api/v2_version.rb +1 -1
- data/lib/ecoportal/api-v2.rb +4 -5
- metadata +6 -5
@@ -1,73 +1,63 @@
|
|
1
|
-
module Ecoportal
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
class DoubleModel
|
6
|
-
module Attributable
|
7
|
-
module Nesting
|
8
|
-
module Embeddable
|
9
|
-
class << self
|
10
|
-
include Content::Includer
|
1
|
+
module Ecoportal::API::Common::Content::DoubleModel::Attributable::Nesting
|
2
|
+
module Embeddable
|
3
|
+
class << self
|
4
|
+
include Ecoportal::API::Common::Content::Includer
|
11
5
|
|
12
|
-
|
13
|
-
|
14
|
-
base.extend Content::ClassHelpers
|
6
|
+
def included(base)
|
7
|
+
super
|
15
8
|
|
16
|
-
|
17
|
-
include_missing(base, DoubleModel::Modifiers)
|
18
|
-
include_missing(base, Attributable::Base)
|
9
|
+
base.extend Ecoportal::API::Common::Content::ClassHelpers
|
19
10
|
|
20
|
-
|
21
|
-
|
11
|
+
include_missing(base, Ecoportal::API::Common::Content::DoubleModel::VarTracking)
|
12
|
+
include_missing(base, Ecoportal::API::Common::Content::DoubleModel::Modifiers)
|
13
|
+
include_missing(base, Ecoportal::API::Common::Content::DoubleModel::Attributable::Base)
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
15
|
+
include_missing(base, Keyable)
|
16
|
+
include_missing(base, CascadedCallback)
|
26
17
|
|
27
|
-
|
28
|
-
|
18
|
+
base.extend ClassMethods
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
private
|
29
24
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
25
|
+
def embed(
|
26
|
+
method,
|
27
|
+
klass:,
|
28
|
+
key: method,
|
29
|
+
nullable: false,
|
30
|
+
multiple: false,
|
31
|
+
read_only: read_only?,
|
32
|
+
&embed_block
|
33
|
+
)
|
34
|
+
method = method.to_s.freeze
|
35
|
+
var = instance_variable_name(method).freeze
|
36
|
+
obj_k = key.to_s.freeze
|
42
37
|
|
43
|
-
|
38
|
+
_cascaded_attribute!(method, obj_k)
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
# retrieving method (getter)
|
41
|
+
define_method(method) do
|
42
|
+
# set item klass as referrer to klass (to allow resolve symbol)
|
43
|
+
embed_block&.call(self)
|
44
|
+
return instance_variable_get(var) if instance_variable_defined?(var)
|
50
45
|
|
51
|
-
|
52
|
-
|
46
|
+
doc[obj_k] ||= (multiple ? [] : {}) unless nullable
|
47
|
+
return variable_set(var, nil) if (doc_value = doc[obj_k]).nil?
|
53
48
|
|
54
|
-
|
55
|
-
|
49
|
+
embedded_class = self.class.resolve_class(klass)
|
50
|
+
items_key_setup!(embedded_class, doc_value) if multiple && read_only
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
52
|
+
embedded_class.new(
|
53
|
+
doc_value,
|
54
|
+
parent: self,
|
55
|
+
key: obj_k,
|
56
|
+
read_only: read_only? || read_only
|
57
|
+
).tap do |collection|
|
58
|
+
variable_set(var, collection)
|
59
|
+
# ensure children classes propagation!
|
60
|
+
_cascaded_attribute!(method, obj_k)
|
71
61
|
end
|
72
62
|
end
|
73
63
|
end
|
@@ -1,118 +1,106 @@
|
|
1
|
-
module Ecoportal
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
define_method "#{method}=" do |value|
|
61
|
-
variable_set(var, value)
|
62
|
-
value = yield(value) if block_given?
|
63
|
-
send(:doc)[method] = value
|
64
|
-
end
|
65
|
-
|
66
|
-
self
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# INSTANCE METHODS
|
71
|
-
|
72
|
-
# @return [String] the `value` of the `key` method (i.e. `id` value)
|
73
|
-
def key
|
74
|
-
msg = "No key_method defined for #{self.class}"
|
75
|
-
raise NoKeyMethod, msg unless key_method?
|
76
|
-
|
77
|
-
method(key_method).call
|
78
|
-
end
|
79
|
-
|
80
|
-
# @param [String] the `value` of the `key` method (i.e. `id` value)
|
81
|
-
def key=(value)
|
82
|
-
msg = "No key_method defined for #{self.class}"
|
83
|
-
raise NoKeyMethod, msg unless key_method?
|
84
|
-
|
85
|
-
method("#{key_method}=").call(value)
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def key_method?
|
91
|
-
self.class.key?
|
92
|
-
end
|
93
|
-
|
94
|
-
def key_method
|
95
|
-
self.class.key
|
96
|
-
end
|
97
|
-
|
98
|
-
# It allows to work-around missing item_key
|
99
|
-
def items_key_setup!(embedded_class, obj_doc)
|
100
|
-
# only if is going to be a collection
|
101
|
-
return unless obj_doc.is_a?(Array) && embedded_class < CollectionModel
|
102
|
-
return unless (item_class = embedded_class.klass)
|
103
|
-
# if already has key don't need to work around
|
104
|
-
return if item_class&.key
|
105
|
-
|
106
|
-
# apply work around
|
107
|
-
item_class.passkey :id
|
108
|
-
obj_doc.each_with_index do |item_doc, idx|
|
109
|
-
item_doc['id'] = idx.to_s unless item_doc.key?('id')
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
1
|
+
module Ecoportal::API::Common::Content::DoubleModel::Attributable::Nesting
|
2
|
+
module Keyable
|
3
|
+
class NoKeyMethod < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
include Ecoportal::API::Common::Content::Includer
|
8
|
+
|
9
|
+
def included(base)
|
10
|
+
super
|
11
|
+
base.extend Ecoportal::API::Common::Content::ClassHelpers
|
12
|
+
|
13
|
+
include_missing(base, Ecoportal::API::Common::Content::DoubleModel::VarTracking)
|
14
|
+
|
15
|
+
base.extend ClassMethods
|
16
|
+
base.inheritable_class_vars :key
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
attr_reader :key
|
22
|
+
|
23
|
+
def key?
|
24
|
+
!!key
|
25
|
+
end
|
26
|
+
|
27
|
+
# key property (and method) of this model
|
28
|
+
# @note this is auto-set when `passkey` is used
|
29
|
+
def key=(value)
|
30
|
+
@key = value.to_s.freeze
|
31
|
+
end
|
32
|
+
|
33
|
+
# This method is essential to give stability to the model
|
34
|
+
# @note `Content::CollectionModel` needs to find elements in the doc `Array`.
|
35
|
+
# The only way to do it is via the access key (i.e. `id`). However, there is
|
36
|
+
# no chance you can avoid infinite loop for `get_key` (CollectionModel)
|
37
|
+
# without setting an instance variable key at the moment of the object creation,
|
38
|
+
# when the `doc` is firstly received
|
39
|
+
# @param method [Symbol] the method that exposes the value
|
40
|
+
# as well as its `key` in the underlying `Hash` model.
|
41
|
+
def passkey(method)
|
42
|
+
method = method.to_s.freeze
|
43
|
+
var = instance_variable_name(method)
|
44
|
+
self.key = method
|
45
|
+
|
46
|
+
define_method method do
|
47
|
+
return instance_variable_get(var) if instance_variable_defined?(var)
|
48
|
+
|
49
|
+
value = send(:doc)[method]
|
50
|
+
value = yield(value) if block_given?
|
51
|
+
value
|
52
|
+
end
|
53
|
+
|
54
|
+
define_method "#{method}=" do |value|
|
55
|
+
variable_set(var, value)
|
56
|
+
value = yield(value) if block_given?
|
57
|
+
send(:doc)[method] = value
|
115
58
|
end
|
59
|
+
|
60
|
+
self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# INSTANCE METHODS
|
65
|
+
|
66
|
+
# @return [String] the `value` of the `key` method (i.e. `id` value)
|
67
|
+
def key
|
68
|
+
msg = "No key_method defined for #{self.class}"
|
69
|
+
raise NoKeyMethod, msg unless key_method?
|
70
|
+
|
71
|
+
method(key_method).call
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [String] the `value` of the `key` method (i.e. `id` value)
|
75
|
+
def key=(value)
|
76
|
+
msg = "No key_method defined for #{self.class}"
|
77
|
+
raise NoKeyMethod, msg unless key_method?
|
78
|
+
|
79
|
+
method("#{key_method}=").call(value)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def key_method?
|
85
|
+
self.class.key?
|
86
|
+
end
|
87
|
+
|
88
|
+
def key_method
|
89
|
+
self.class.key
|
90
|
+
end
|
91
|
+
|
92
|
+
# It allows to work-around missing item_key
|
93
|
+
def items_key_setup!(embedded_class, obj_doc)
|
94
|
+
# only if is going to be a collection
|
95
|
+
return unless obj_doc.is_a?(Array) && embedded_class < CollectionModel
|
96
|
+
return unless (item_class = embedded_class.klass)
|
97
|
+
# if already has key don't need to work around
|
98
|
+
return if item_class&.key
|
99
|
+
|
100
|
+
# apply work around
|
101
|
+
item_class.passkey :id
|
102
|
+
obj_doc.each_with_index do |item_doc, idx|
|
103
|
+
item_doc['id'] = idx.to_s unless item_doc.key?('id')
|
116
104
|
end
|
117
105
|
end
|
118
106
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'ecoportal/api/common/content/double_model/attributable/nesting/keyable'
|
2
|
-
require 'ecoportal/api/common/content/double_model/attributable/nesting/cascaded_callback'
|
3
|
-
require 'ecoportal/api/common/content/double_model/attributable/nesting/embeddable'
|
4
1
|
module Ecoportal
|
5
2
|
module API
|
6
3
|
module Common
|
@@ -8,6 +5,10 @@ module Ecoportal
|
|
8
5
|
class DoubleModel
|
9
6
|
module Attributable
|
10
7
|
module Nesting
|
8
|
+
require_relative 'nesting/keyable'
|
9
|
+
require_relative 'nesting/cascaded_callback'
|
10
|
+
require_relative 'nesting/embeddable'
|
11
|
+
|
11
12
|
class << self
|
12
13
|
include Content::Includer
|
13
14
|
|
@@ -56,6 +57,7 @@ module Ecoportal
|
|
56
57
|
read_only: read_only?
|
57
58
|
).tap do |new_obj|
|
58
59
|
variable_set(var, new_obj)
|
60
|
+
# ensure children classes propagation!
|
59
61
|
_cascaded_attribute!(method)
|
60
62
|
end
|
61
63
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require_relative 'attributable/base'
|
2
|
+
require_relative 'attributable/passthrough'
|
3
|
+
require_relative 'attributable/enforce'
|
4
|
+
require_relative 'attributable/simple'
|
5
|
+
require_relative 'attributable/nesting'
|
6
6
|
module Ecoportal
|
7
7
|
module API
|
8
8
|
module Common
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ecoportal::API::Common::Content::DoubleModel::Diffable
|
2
|
+
class DiffService
|
3
|
+
include Ecoportal::API::Common::Content::HashDiffPatch
|
4
|
+
|
5
|
+
attr_reader :subject
|
6
|
+
|
7
|
+
def initialize(subject)
|
8
|
+
@subject = subject
|
9
|
+
end
|
10
|
+
|
11
|
+
def path_diff
|
12
|
+
super(
|
13
|
+
curr_doc,
|
14
|
+
prev_doc
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def prev_doc(obj = subject)
|
21
|
+
return obj.original_doc if obj.respond_to?(:original_doc)
|
22
|
+
|
23
|
+
raise "Instance of (#{subject.class}): can't fetch original underlying model"
|
24
|
+
end
|
25
|
+
|
26
|
+
def curr_doc(obj = subject)
|
27
|
+
return obj.as_json if obj.respond_to?(:as_json)
|
28
|
+
return obj.doc if obj.respond_to?(:doc)
|
29
|
+
|
30
|
+
raise "Instance of (#{subject.class}): can't fetch underlying document"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -3,7 +3,11 @@ module Ecoportal
|
|
3
3
|
module Common
|
4
4
|
module Content
|
5
5
|
class DoubleModel
|
6
|
-
module
|
6
|
+
module Diffable
|
7
|
+
require_relative 'diffable/diff_service'
|
8
|
+
|
9
|
+
DIFF_CLASS = DiffService
|
10
|
+
|
7
11
|
class << self
|
8
12
|
include Content::Includer
|
9
13
|
|
@@ -21,10 +25,7 @@ module Ecoportal
|
|
21
25
|
# @return [nil, Hash] the patch `Hash` model including only
|
22
26
|
# the changes between `original_doc` and `doc`.
|
23
27
|
def as_update
|
24
|
-
|
25
|
-
as_json,
|
26
|
-
original_doc
|
27
|
-
)
|
28
|
+
diff_class.new(self).path_diff
|
28
29
|
end
|
29
30
|
|
30
31
|
# @return [Boolean] stating if there are changes.
|
@@ -35,6 +36,12 @@ module Ecoportal
|
|
35
36
|
|
36
37
|
true
|
37
38
|
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def diff_class
|
43
|
+
self.class::DIFF_CLASS
|
44
|
+
end
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
@@ -7,8 +7,10 @@ module Ecoportal
|
|
7
7
|
module LinkableDoc
|
8
8
|
class UnlinkedModel < StandardError
|
9
9
|
def initialize(msg = "Something went wrong when linking the document.", from: nil, key: nil)
|
10
|
-
msg
|
11
|
-
msg
|
10
|
+
msg ||= ''
|
11
|
+
msg << " From: #{from}." if from
|
12
|
+
msg << " key: #{key}." if key
|
13
|
+
|
12
14
|
super(msg)
|
13
15
|
end
|
14
16
|
end
|
@@ -26,8 +28,8 @@ module Ecoportal
|
|
26
28
|
|
27
29
|
# INSTANCE METHODS
|
28
30
|
|
29
|
-
def to_json(
|
30
|
-
doc.to_json(
|
31
|
+
def to_json(...)
|
32
|
+
doc.to_json(...)
|
31
33
|
end
|
32
34
|
|
33
35
|
def as_json
|
@@ -39,6 +41,9 @@ module Ecoportal
|
|
39
41
|
self
|
40
42
|
end
|
41
43
|
|
44
|
+
# @note when `doc` isn't rooted, it relies to the `_parent.doc`.
|
45
|
+
# This does a `doc` recursive resolve, where `resolved_rooted_doc_key`
|
46
|
+
# can only have 1 level at each iteration.
|
42
47
|
# @return [nil, Hash] the underlying `Hash` model as is (carrying current changes)
|
43
48
|
def doc
|
44
49
|
return @doc if doc_var?
|
@@ -32,7 +32,11 @@ module Ecoportal
|
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
35
|
-
dig_set(
|
35
|
+
dig_set!(
|
36
|
+
_parent.doc,
|
37
|
+
resolved_rooted_doc_key,
|
38
|
+
new_doc
|
39
|
+
)
|
36
40
|
|
37
41
|
_parent.variable_remove!(_parent_key) unless new_doc
|
38
42
|
#variables_remove!
|
@@ -50,7 +54,11 @@ module Ecoportal
|
|
50
54
|
)
|
51
55
|
end
|
52
56
|
|
53
|
-
dig_set(
|
57
|
+
dig_set!(
|
58
|
+
_parent.original_doc,
|
59
|
+
resolved_rooted_doc_key,
|
60
|
+
new_doc
|
61
|
+
)
|
54
62
|
end
|
55
63
|
end
|
56
64
|
end
|
@@ -19,9 +19,17 @@ module Ecoportal
|
|
19
19
|
|
20
20
|
# Offers a method for child classes to transform the key,
|
21
21
|
# provided that the child's `doc` can be accessed.
|
22
|
+
# @note this method was introduced with `CollectionModel`. The individual
|
23
|
+
# elements/items wouldn't know how to fetch their own model via their
|
24
|
+
# parent. This required to introduce _rooted_doc_key in all DoubleModel
|
25
|
+
# ancestors. It just delegates up the resolution of a `value` key.
|
22
26
|
# @note this method can't be protected. It might be accessed by cousing classes.
|
23
|
-
# See last line of this method.
|
24
27
|
# parent class to a child class.
|
28
|
+
# See last line of this method.
|
29
|
+
# @param value [Content::DoubleModel, Array<String>, String]
|
30
|
+
# - `String` or `Array<String>`: is mirrored.
|
31
|
+
# - `DoubleModel` and `root?`: is mirrored.
|
32
|
+
# - non `root?` `DoubleModel`: deletages to `_parent`
|
25
33
|
def _rooted_doc_key(value)
|
26
34
|
#print "!(#{value}<=#{self.class})" if value.is_a?(Content::DoubleModel) && !value.root?
|
27
35
|
return value unless value.is_a?(Content::DoubleModel)
|
@@ -30,16 +38,15 @@ module Ecoportal
|
|
30
38
|
#print "?(#{value.class}<=#{value._parent.class})"
|
31
39
|
value._parent._rooted_doc_key(value)
|
32
40
|
end
|
33
|
-
# alias_method :_doc_key, :_rooted_doc_key
|
34
41
|
|
35
42
|
protected
|
36
43
|
|
44
|
+
# @note it assumes it is `Parented`
|
37
45
|
# @note this method can be protected... not accessed from
|
38
46
|
# parent class to child class.
|
39
47
|
def resolved_rooted_doc_key
|
40
48
|
[_rooted_doc_key(_parent_key)].flatten
|
41
49
|
end
|
42
|
-
# alias_method :resolved_doc_key, :resolved_rooted_doc_key
|
43
50
|
end
|
44
51
|
end
|
45
52
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require_relative 'double_doc/base'
|
2
|
+
require_relative 'double_doc/rooted_key'
|
3
|
+
require_relative 'double_doc/linkable_doc'
|
4
|
+
require_relative 'double_doc/replaceable_doc'
|
5
|
+
require_relative 'double_doc/reset_consolidate'
|
6
6
|
|
7
7
|
module Ecoportal
|
8
8
|
module API
|
@@ -6,14 +6,30 @@ module Ecoportal
|
|
6
6
|
module HashHelpers
|
7
7
|
private
|
8
8
|
|
9
|
+
# @return [Boolean] whether the path (beginning) of the last key
|
10
|
+
# exists from `obj`.
|
11
|
+
def dig_path?(obj, keys)
|
12
|
+
return false unless obj.respond_to?([])
|
13
|
+
return true if keys.length == 1
|
14
|
+
|
15
|
+
dig_path?(
|
16
|
+
obj[keys.first],
|
17
|
+
keys[1..]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
9
21
|
# It sets `value` on the last object that you would get
|
10
22
|
# via `obj.dig(*keys[0..-1])`
|
11
23
|
# @note equivalent to `obj.dig(*keys[0..-1])&[keys.last] = value`
|
12
|
-
def dig_set(obj, keys, value)
|
24
|
+
def dig_set!(obj, keys, value)
|
13
25
|
if keys.length == 1
|
14
26
|
obj[keys.first] = value
|
15
27
|
else
|
16
|
-
dig_set(
|
28
|
+
dig_set!(
|
29
|
+
obj[keys.first],
|
30
|
+
keys[1..],
|
31
|
+
value
|
32
|
+
)
|
17
33
|
end
|
18
34
|
end
|
19
35
|
|
@@ -23,13 +39,16 @@ module Ecoportal
|
|
23
39
|
# 1. `parent = obj.dig(*keys[0..-1])`
|
24
40
|
# 2. `parent.delete(keys.last) if parent.is_a?(Hash)`
|
25
41
|
# @return [Variant] the value of that key
|
26
|
-
def dig_delete(obj, keys)
|
42
|
+
def dig_delete!(obj, keys)
|
27
43
|
if keys.length == 1
|
28
44
|
return unless obj.respond_to?(:delete)
|
29
45
|
|
30
46
|
obj.delete(keys.first)
|
31
47
|
else
|
32
|
-
dig_delete(
|
48
|
+
dig_delete!(
|
49
|
+
obj[keys.first],
|
50
|
+
keys[1..]
|
51
|
+
)
|
33
52
|
end
|
34
53
|
end
|
35
54
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'modifiers/rootable'
|
2
|
+
require_relative 'modifiers/read_only_able'
|
3
3
|
|
4
4
|
module Ecoportal
|
5
5
|
module API
|