ecoportal-api-v2 2.0.11 → 2.0.14

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +35 -1
  4. data/ecoportal-api-v2.gemspec +1 -1
  5. data/lib/ecoportal/api/common/content/array_model.rb +20 -3
  6. data/lib/ecoportal/api/common/content/class_helpers.rb +4 -2
  7. data/lib/ecoportal/api/common/content/client.rb +12 -6
  8. data/lib/ecoportal/api/common/content/collection_model/doc/items.rb +33 -0
  9. data/lib/ecoportal/api/common/content/collection_model/doc/rooted_key.rb +68 -0
  10. data/lib/ecoportal/api/common/content/collection_model/doc.rb +25 -0
  11. data/lib/ecoportal/api/common/content/collection_model/doc_mutation/delete.rb +33 -0
  12. data/lib/ecoportal/api/common/content/collection_model/doc_mutation/position.rb +42 -0
  13. data/lib/ecoportal/api/common/content/collection_model/doc_mutation/upsert.rb +45 -0
  14. data/lib/ecoportal/api/common/content/collection_model/doc_mutation.rb +27 -0
  15. data/lib/ecoportal/api/common/content/collection_model/model/cache.rb +44 -0
  16. data/lib/ecoportal/api/common/content/collection_model/model/items.rb +43 -0
  17. data/lib/ecoportal/api/common/content/collection_model/model/iterable.rb +44 -0
  18. data/lib/ecoportal/api/common/content/collection_model/model/lookup.rb +45 -0
  19. data/lib/ecoportal/api/common/content/collection_model/model/numeric_key.rb +40 -0
  20. data/lib/ecoportal/api/common/content/collection_model/model/var_tracking.rb +50 -0
  21. data/lib/ecoportal/api/common/content/collection_model/model.rb +33 -0
  22. data/lib/ecoportal/api/common/content/collection_model/modifiers/items_key.rb +57 -0
  23. data/lib/ecoportal/api/common/content/collection_model/modifiers/items_klass.rb +144 -0
  24. data/lib/ecoportal/api/common/content/collection_model/modifiers/items_order.rb +38 -0
  25. data/lib/ecoportal/api/common/content/collection_model/modifiers.rb +27 -0
  26. data/lib/ecoportal/api/common/content/collection_model/mutation/clear.rb +30 -0
  27. data/lib/ecoportal/api/common/content/collection_model/mutation/delete.rb +42 -0
  28. data/lib/ecoportal/api/common/content/collection_model/mutation/upsert.rb +56 -0
  29. data/lib/ecoportal/api/common/content/collection_model/mutation.rb +27 -0
  30. data/lib/ecoportal/api/common/content/collection_model.rb +19 -351
  31. data/lib/ecoportal/api/common/content/doc_helpers.rb +18 -16
  32. data/lib/ecoportal/api/common/content/double_model/attributable/base.rb +23 -0
  33. data/lib/ecoportal/api/common/content/double_model/attributable/enforce.rb +62 -0
  34. data/lib/ecoportal/api/common/content/double_model/attributable/nesting/cascaded_callback.rb +104 -0
  35. data/lib/ecoportal/api/common/content/double_model/attributable/nesting/embeddable.rb +76 -0
  36. data/lib/ecoportal/api/common/content/double_model/attributable/nesting/keyable.rb +119 -0
  37. data/lib/ecoportal/api/common/content/double_model/attributable/nesting.rb +136 -0
  38. data/lib/ecoportal/api/common/content/double_model/attributable/passthrough.rb +70 -0
  39. data/lib/ecoportal/api/common/content/double_model/attributable/simple.rb +48 -0
  40. data/lib/ecoportal/api/common/content/double_model/attributable.rb +30 -0
  41. data/lib/ecoportal/api/common/content/double_model/base.rb +29 -0
  42. data/lib/ecoportal/api/common/content/double_model/diffable_model.rb +43 -0
  43. data/lib/ecoportal/api/common/content/double_model/double_doc/base.rb +23 -0
  44. data/lib/ecoportal/api/common/content/double_model/double_doc/linkable_doc.rb +87 -0
  45. data/lib/ecoportal/api/common/content/double_model/double_doc/replaceable_doc.rb +61 -0
  46. data/lib/ecoportal/api/common/content/double_model/double_doc/reset_consolidate.rb +54 -0
  47. data/lib/ecoportal/api/common/content/double_model/double_doc/rooted_key.rb +49 -0
  48. data/lib/ecoportal/api/common/content/double_model/double_doc.rb +31 -0
  49. data/lib/ecoportal/api/common/content/double_model/hash_helpers.rb +40 -0
  50. data/lib/ecoportal/api/common/content/double_model/modifiers/read_only_able.rb +73 -0
  51. data/lib/ecoportal/api/common/content/double_model/modifiers/rootable.rb +64 -0
  52. data/lib/ecoportal/api/common/content/double_model/modifiers.rb +24 -0
  53. data/lib/ecoportal/api/common/content/double_model/parented.rb +22 -0
  54. data/lib/ecoportal/api/common/content/double_model/var_tracking.rb +45 -0
  55. data/lib/ecoportal/api/common/content/double_model.rb +28 -486
  56. data/lib/ecoportal/api/common/content/hash_diff_patch.rb +2 -1
  57. data/lib/ecoportal/api/common/content/includer.rb +16 -0
  58. data/lib/ecoportal/api/common/content/model_helpers.rb +14 -16
  59. data/lib/ecoportal/api/common/content.rb +1 -0
  60. data/lib/ecoportal/api/v2/page/component.rb +46 -46
  61. data/lib/ecoportal/api/v2/page/components.rb +2 -2
  62. data/lib/ecoportal/api/v2/page.rb +14 -14
  63. data/lib/ecoportal/api/v2/pages/page_stage/task.rb +2 -2
  64. data/lib/ecoportal/api/v2/pages/page_stage/tasks.rb +3 -3
  65. data/lib/ecoportal/api/v2/pages/page_stage.rb +8 -8
  66. data/lib/ecoportal/api/v2/pages/stages.rb +2 -2
  67. data/lib/ecoportal/api/v2/pages.rb +15 -15
  68. data/lib/ecoportal/api/v2/registers.rb +20 -19
  69. data/lib/ecoportal/api/v2/s3/files/batch_upload.rb +1 -0
  70. data/lib/ecoportal/api/v2/s3/files/poll.rb +5 -5
  71. data/lib/ecoportal/api/v2/s3/files/poll_status.rb +3 -3
  72. data/lib/ecoportal/api/v2/s3/files.rb +6 -6
  73. data/lib/ecoportal/api/v2/s3.rb +5 -5
  74. data/lib/ecoportal/api/v2.rb +18 -8
  75. data/lib/ecoportal/api/v2_version.rb +1 -1
  76. metadata +51 -5
@@ -6,471 +6,52 @@ module Ecoportal
6
6
  # which differs of `attr_*` ruby native class methods because `pass*`
7
7
  # completelly **links** the methods **to a subjacent `Hash` model**
8
8
  class DoubleModel < Ecoportal::API::Common::BaseModel
9
- class UnlinkedModel < StandardError
10
- def initialize(msg = "Something went wrong when linking the document.", from: nil, key: nil)
11
- msg += " From: #{from}." if from
12
- msg += " key: #{key}." if key
13
- super(msg)
14
- end
15
- end
16
-
17
- class NoKeyMethod < StandardError
18
- end
19
-
20
- NOT_USED = ClassHelpers::NOT_USED
21
- extend ClassHelpers
22
- include ModelHelpers
9
+ require 'ecoportal/api/common/content/double_model/base'
10
+ require 'ecoportal/api/common/content/double_model/parented'
11
+ require 'ecoportal/api/common/content/double_model/modifiers'
12
+ require 'ecoportal/api/common/content/double_model/var_tracking'
13
+ require 'ecoportal/api/common/content/double_model/hash_helpers'
14
+ require 'ecoportal/api/common/content/double_model/double_doc'
15
+ require 'ecoportal/api/common/content/double_model/attributable'
16
+ require 'ecoportal/api/common/content/double_model/diffable_model'
17
+
18
+ include Base
19
+ include Parented
20
+ include Modifiers
21
+ include VarTracking
22
+ include HashHelpers
23
+
24
+ include DoubleDoc
25
+ include Attributable
26
+ include DiffableModel
23
27
 
24
28
  class << self
25
- attr_reader :key
26
-
27
- def key?
28
- !!key
29
- end
30
-
31
- # key property (and method) of this model
32
- # @note this is auto-set when `passkey` is used
33
- def key=(value)
34
- @key = value.to_s.freeze
35
- end
36
-
37
29
  def new_uuid(length: 24)
38
30
  uid(length)
39
31
  end
40
-
41
- def read_only?
42
- @read_only = false if @read_only.nil?
43
- @read_only
44
- end
45
-
46
- # Be able to define if a class should be read-only
47
- def read_only!
48
- @read_only = true
49
- end
50
-
51
- # Same as `attr_reader` but links to a subjacent `Hash` model property
52
- # @note it does **not** create an _instance variable_
53
- # @param methods [Array<Symbol>] the method that exposes the value
54
- # as well as its `key` in the underlying `Hash` model.
55
- def pass_reader(*methods)
56
- methods.each do |method|
57
- method = method.to_s.freeze
58
-
59
- define_method method do
60
- value = send(:doc)[method]
61
- value = yield(value) if block_given?
62
- value
63
- end
64
- end
65
- self
66
- end
67
-
68
- # Same as `attr_writer` but links to a subjacent `Hash` model property
69
- # @note it does **not** create an _instance variable_
70
- # @param methods [Array<Symbol>] the method that exposes the value
71
- # as well as its `key` in the underlying `Hash` model.
72
- def pass_writer(*methods)
73
- methods.each do |method|
74
- method = method.to_s.freeze
75
-
76
- define_method "#{method}=" do |value|
77
- value = yield(value) if block_given?
78
- send(:doc)[method] = value
79
- end
80
- end
81
- self
82
- end
83
-
84
- # This method is essential to give stability to the model
85
- # @note `Content::CollectionModel` needs to find elements in the doc `Array`.
86
- # The only way to do it is via the access key (i.e. `id`). However, there is
87
- # no chance you can avoid infinite loop for `get_key` without setting an
88
- # instance variable key at the moment of the object creation, when the
89
- # `doc` is firstly received
90
- # @param method [Symbol] the method that exposes the value
91
- # as well as its `key` in the underlying `Hash` model.
92
- def passkey(method)
93
- method = method.to_s.freeze
94
- var = instance_variable_name(method)
95
- self.key = method
96
-
97
- define_method method do
98
- return instance_variable_get(var) if instance_variable_defined?(var)
99
- value = send(:doc)[method]
100
- value = yield(value) if block_given?
101
- value
102
- end
103
-
104
- define_method "#{method}=" do |value|
105
- variable_set(var, value)
106
- value = yield(value) if block_given?
107
- send(:doc)[method] = value
108
- end
109
-
110
- self
111
- end
112
-
113
- # These are methods that should always be present in patch update
114
- # @note
115
- # - `DoubleModel` can be used with objects that do not use `patch_ver`
116
- # - This ensures that does that do, will get the correct patch update model
117
- # @param method [Symbol] the method that exposes the value
118
- # as well as its `key` in the underlying `Hash` model.
119
- # @param default [Value] the default value that
120
- # this `key` will be written in the model when it doesn't exixt
121
- def passforced(method, default:, read_only: false)
122
- model_forced_keys[method.to_s.freeze] = default
123
- passthrough(method, read_only: read_only)
124
- end
125
-
126
- # Ensures `doc` has the `model_forced_keys`. If it doesn't, it adds those missing
127
- # with the defined `default` values
128
- def enforce!(doc)
129
- return unless doc.is_a?(Hash)
130
- return if model_forced_keys.empty?
131
-
132
- model_forced_keys.each do |key, default|
133
- doc[key] = default unless doc.key?(key)
134
- end
135
- doc
136
- end
137
-
138
- # Same as `attr_accessor` but links to a subjacent `Hash` model property
139
- # @param methods [Array<Symbol>] the method that exposes the value
140
- # as well as its `key` in the underlying `Hash` model.
141
- # @param read_only [Boolean] should it only define the reader?
142
- def passthrough(*methods, read_only: false)
143
- pass_reader(*methods)
144
- pass_writer(*methods) unless read_only
145
- self
146
- end
147
-
148
- # To link as a `Time` date to a subjacent `Hash` model property
149
- # @see Ecoportal::API::Common::Content::DoubleModel#passthrough
150
- # @param methods [Array<Symbol>] the method that exposes the value
151
- # as well as its `key` in the underlying `Hash` model.
152
- # @param read_only [Boolean] should it only define the reader?
153
- def passdate(*methods, read_only: false)
154
- pass_reader(*methods) {|value| to_time(value)}
155
- pass_writer(*methods) {|value| to_time(value)&.iso8601} unless read_only
156
- self
157
- end
158
-
159
- # To link as a `Boolean` to a subjacent `Hash` model property
160
- # @param methods [Array<Symbol>] the method that exposes the value
161
- # as well as its `key` in the underlying `Hash` model.
162
- # @param read_only [Boolean] should it only define the reader?
163
- def passboolean(*methods, read_only: false)
164
- pass_reader(*methods) {|value| value}
165
- pass_writer(*methods) {|value| !!value} unless read_only
166
- self
167
- end
168
-
169
- # To link as plain `Array` to a subjacent `Hash` model property
170
- # @param methods [Array<Symbol>] the method that exposes the value
171
- # as well as its `key` in the underlying `Hash` model.
172
- # @param order_matters [Boolean] does the order matter
173
- # @param uniq [Boolean] should it contain unique elements
174
- def passarray(*methods, order_matters: true, uniq: true)
175
- methods.each do |method|
176
- method = method.to_s.freeze
177
- var = instance_variable_name(method)
178
-
179
- dim_class = new_class(method, inherits: ArrayModel) do |klass|
180
- klass.order_matters = order_matters
181
- klass.uniq = uniq
182
- end
183
-
184
- define_method method do
185
- return instance_variable_get(var) if instance_variable_defined?(var)
186
- new_obj = dim_class.new(parent: self, key: method, read_only: read_only?)
187
- variable_set(var, new_obj)
188
- end
189
- end
190
- end
191
-
192
- # Helper to embed one nested object under one property
193
- # @param method [Symbol] the method that exposes the embeded object
194
- # @param key [Symbol] the `key` that embeds it to the underlying `Hash` model
195
- # @nullable [Boolean] to specify if this object can be `nil`
196
- # @param klass [Class, String] the class of the embedded object
197
- def embeds_one(method, klass:, key: method, nullable: false)
198
- embed(method, key: key, nullable: nullable, multiple: false, klass: klass)
199
- end
200
-
201
- # @note
202
- # - if you have a dedicated `Enumerable` class to manage `many`, you should use `:enum_class`
203
- # - otherwise, just indicate the child class in `:klass` and it will auto generate the class
204
- # @param method [Symbol] the method that exposes the embeded object
205
- # @param key [Symbol] the `key` that embeds it to the underlying `Hash` model
206
- # @param order_matters [Boolean] to state if the order will matter
207
- # @param klass [Class, String] the class of the individual elements it embeds
208
- # @param enum_class [Class, String] the class of the collection that will hold the individual elements
209
- # @param read_only [Boolean] whether or not should try to **work around** items `klass` missing a `key`
210
- # - If set to `true` this is meant only for read purposes (won't be able to successufully insert)
211
- def embeds_many(method, key: method, klass: nil, enum_class: nil,
212
- order_matters: false, order_key: nil, read_only: read_only?)
213
- if enum_class
214
- eclass = enum_class
215
- elsif klass
216
- eclass = new_class("#{method}::#{klass}", inherits: CollectionModel) do |dim_class|
217
- # NOTE: new_class may resolve the namespace of the class to an already existing class
218
- dim_class.klass ||= klass
219
- dim_class.order_matters = order_matters
220
- dim_class.order_key = order_key
221
- dim_class.read_only! if read_only
222
- end
223
- else
224
- raise "You should either specify the 'klass' of the elements or the 'enum_class'"
225
- end
226
-
227
- embed(
228
- method, key: key,
229
- multiple: true, klass: eclass,
230
- read_only: read_only
231
- ) do |instance_with_called_method|
232
- # keep reference to the original class to resolve the `klass` dependency
233
- # See stackoverflow: https://stackoverflow.com/a/73709529/4352306
234
- referrer_class = instance_with_called_method.class
235
- eclass.klass = {referrer_class => klass} if klass
236
- # This helps `resolve_class` to correctly resolve a symbol
237
- # by using referrer_class as a base module to resolve it
238
- end
239
- end
240
-
241
- private
242
-
243
- def embed(
244
- method, klass:, key: method,
245
- nullable: false, multiple: false, read_only: read_only?,
246
- &embed_block
247
- )
248
- method = method.to_s.freeze
249
- var = instance_variable_name(method).freeze
250
- obj_k = key.to_s.freeze
251
-
252
- # retrieving method (getter)
253
- define_method(method) do
254
- # set item klass as referrer to klass (to allow resolve symbol)
255
- embed_block&.call(self)
256
- return instance_variable_get(var) if instance_variable_defined?(var)
257
-
258
- doc[obj_k] ||= (multiple ? [] : {}) unless nullable
259
- return variable_set(var, nil) unless doc[obj_k]
260
-
261
- embedded_class = self.class.resolve_class(klass)
262
- setup_items_key(embedded_class, doc[obj_k]) if multiple && read_only
263
-
264
- embedded_class.new(
265
- doc[obj_k],
266
- parent: self,
267
- key: obj_k,
268
- read_only: read_only? || read_only
269
- ).tap do |collection|
270
- variable_set(var, collection)
271
- end
272
- end
273
- end
274
-
275
- # The list of keys that will be forced in the model
276
- def model_forced_keys
277
- @model_forced_keys ||= {}
278
- end
279
32
  end
280
33
 
281
- inheritable_class_vars :model_forced_keys, :key, :read_only
282
-
283
- # `_key` refers to the `_parent`'s property that links to this model
284
- # @note while `key` refers to the value of theproperty of this model
285
- # that is key (identifies an item in a set of elements)
286
- attr_reader :_parent, :_key, :_read_only
287
-
288
34
  def initialize(doc = {}, parent: self, key: nil, read_only: self.class.read_only?) # rubocop:disable Lint/MissingSuper
289
- @_dim_vars = []
290
- @_parent = parent || self
291
- @_key = key || self
292
- @_read_only = read_only
35
+ self._parent = parent || self
36
+ self._parent_key = key || self
37
+
38
+ read_only! if read_only
293
39
 
294
40
  self.class.enforce!(doc)
295
41
 
296
- if (_parent == self) || read_only
297
- @doc = JSON.parse(doc.to_json)
298
- @original_doc = JSON.parse(@doc.to_json)
42
+ if to_be_root?
43
+ @doc = JSON.parse(doc.to_json)
44
+ @original_doc = JSON.parse(@doc.to_json)
299
45
  end
300
46
 
301
- return unless key_method? && doc && doc.is_a?(Hash)
47
+ return unless key_method? && doc.is_a?(Hash)
302
48
 
49
+ # ensure it is well linked! (so: throw error if something is wrong!)
50
+ # and ensure the below does not create an infinite loop
303
51
  self.key = doc[key_method]
304
52
  #puts "\n$(#{self.key}<=>#{self.class})"
305
53
  end
306
54
 
307
- # @note `read_only` allows for some optimizations, such as storing values
308
- # in instance variables, for optimization purposes
309
- def read_only?
310
- @_read_only
311
- end
312
-
313
- def root
314
- return self if is_root?
315
- _parent.root
316
- end
317
-
318
- # @return [String] the `value` of the `key` method (i.e. `id` value)
319
- def key
320
- raise NoKeyMethod, "No key_method defined for #{self.class}" unless key_method?
321
-
322
- method(key_method).call
323
- end
324
-
325
- # @param [String] the `value` of the `key` method (i.e. `id` value)
326
- def key=(value)
327
- raise NoKeyMethod, "No key_method defined for #{self.class}" unless key_method?
328
-
329
- method("#{key_method}=").call(value)
330
- end
331
-
332
- def resolved_doc_key
333
- [_doc_key(_key)]
334
- end
335
-
336
- # Offers a method for child classes to transform the key,
337
- # provided that the child's `doc` can be accessed
338
- def _doc_key(value)
339
- if value.is_a?(Content::DoubleModel) && !value.is_root?
340
- #print "?(#{value.class}<=#{value._parent.class})"
341
- value._parent._doc_key(value)
342
- else
343
- #print "!(#{value}<=#{self.class})"
344
- value
345
- end
346
- end
347
-
348
- # @return [nil, Hash] the underlying `Hash` model as is (carrying current changes)
349
- def doc
350
- return @doc if doc_var?
351
-
352
- raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
353
- return @doc if is_root?
354
-
355
- # transform parent's `_key` to this object into a
356
- # path key that can rerieve from the parents's doc
357
- _parent.doc.dig(*resolved_doc_key.flatten)
358
- end
359
-
360
- # The `original_doc` holds the model as is now on server-side.
361
- # @return [nil, Hash] the underlying `Hash` model as after last `consolidate!` changes
362
- def original_doc
363
- raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked?
364
- return @original_doc if is_root?
365
-
366
- _parent.original_doc.dig(*resolved_doc_key.flatten)
367
- end
368
-
369
- def as_json
370
- doc
371
- end
372
-
373
- def to_json(*args)
374
- doc.to_json(*args)
375
- end
376
-
377
- # @return [nil, Hash] the patch `Hash` model including only the changes between
378
- # `original_doc` and `doc`
379
- def as_update
380
- new_doc = as_json
381
- HashDiffPatch.patch_diff(new_doc, original_doc)
382
- end
383
-
384
- # @return [Boolean] stating if there are changes
385
- def dirty?
386
- au = as_update
387
- !((au == {}) || au.nil?)
388
- end
389
-
390
- # It makes `original_doc` to be like `doc`
391
- # @note
392
- # - after executing it, there will be no pending changes
393
- # - you should technically run this command, after a successful update request to the server
394
- def consolidate!
395
- replace_original_doc(JSON.parse(doc.to_json))
396
- end
397
-
398
- # It makes `doc` to be like `original`
399
- # @note
400
- # - after executing it, changes in `doc` will be lost
401
- # - you should technically run this command only if you want to remove certain changes
402
- # @key [Symbol] the specific part of the model you want to `reset`
403
- def reset!(key = nil)
404
- if key
405
- keys = [key].flatten.compact
406
- odoc = original_doc.dig(*keys)
407
- odoc &&= JSON.parse(odoc.to_json)
408
- dig_set(doc, keys, odoc)
409
- else
410
- replace_doc(JSON.parse(original_doc.to_json))
411
- end
412
- end
413
-
414
- def print_pretty
415
- puts JSON.pretty_generate(as_json)
416
- self
417
- end
418
-
419
- def replace_doc(new_doc)
420
- raise UnlinkedModel.new(from: "#{self.class}#replace_doc", key: _key) unless linked?
421
- return (@doc = new_doc) if is_root?
422
-
423
- dig_set(_parent.doc, resolved_doc_key.flatten, new_doc)
424
- _parent.variable_remove!(_key) unless new_doc
425
- #variables_remove!
426
- end
427
-
428
- protected
429
-
430
- def doc_var?
431
- !!defined?(@doc)
432
- end
433
-
434
- # Both requisites
435
- # @note that for optimization purposes, `@doc` var may be used when
436
- # the object is `read_only?`
437
- def is_root?
438
- _parent == self && doc_var?
439
- end
440
-
441
- def linked?
442
- is_root? || !!_parent.doc
443
- end
444
-
445
- def replace_original_doc(new_doc)
446
- raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
447
- return (@original_doc = new_doc) if is_root?
448
-
449
- dig_set(_parent.original_doc, resolved_doc_key.flatten, new_doc)
450
- end
451
-
452
- # Helper to track down persistent variables
453
- def variable_set(key, value)
454
- var = instance_variable_name(key)
455
- @_dim_vars.push(var).uniq!
456
- instance_variable_set(var, value)
457
- end
458
-
459
- # Helper to remove tracked down instance variables
460
- def variable_remove!(key)
461
- var = instance_variable_name(key)
462
- return unless @_dim_vars.include?(var)
463
-
464
- @_dim_vars.delete(var)
465
- remove_instance_variable(var)
466
- end
467
-
468
- # Removes all the persistent variables
469
- def variables_remove!
470
- #puts "going to remove vars: #{@_dim_vars} on #{self.class} (parent: #{identify_parent(self._parent)})"
471
- @_dim_vars.dup.map {|var| variable_remove!(var)}
472
- end
473
-
474
55
  private
475
56
 
476
57
  def identify_parent(object)
@@ -481,45 +62,6 @@ module Ecoportal
481
62
  "section #{object.heading}"
482
63
  end
483
64
  end
484
-
485
- def instance_variable_name(key)
486
- self.class.instance_variable_name(key)
487
- end
488
-
489
- def dig_set(obj, keys, value)
490
- if keys.length == 1
491
- obj[keys.first] = value
492
- else
493
- dig_set(obj[keys.first], keys.slice(1..-1), value)
494
- end
495
- end
496
-
497
- def used_param?(val)
498
- self.class.used_param?(val)
499
- end
500
-
501
- def key_method?
502
- self.class.key?
503
- end
504
-
505
- def key_method
506
- self.class.key
507
- end
508
-
509
- # It allows to work-around missing item_key
510
- def setup_items_key(embedded_class, obj_doc)
511
- # only if is going to be a collection
512
- return unless obj_doc.is_a?(Array) && embedded_class < CollectionModel
513
- return unless (item_class = embedded_class.klass)
514
- # if already has key don't need to work around
515
- return if item_class&.key
516
-
517
- # apply work around
518
- item_class.passkey :id
519
- obj_doc.each_with_index do |item_doc, idx|
520
- item_doc["id"] = idx.to_s unless item_doc.key?("id")
521
- end
522
- end
523
65
  end
524
66
  end
525
67
  end
@@ -61,6 +61,7 @@ module Ecoportal
61
61
 
62
62
  return true if a_empty && b_empty
63
63
  end
64
+
64
65
  a == b
65
66
  end
66
67
 
@@ -98,7 +99,7 @@ module Ecoportal
98
99
  data_hash['patch_ver'] = a['patch_ver']
99
100
  end
100
101
 
101
- data_hash.delete("force_patch")
102
+ data_hash.delete('force_patch')
102
103
  end
103
104
  end
104
105
 
@@ -0,0 +1,16 @@
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ module Content
5
+ module Includer
6
+ def include_missing(base, target)
7
+ return base if base <= target
8
+
9
+ base.send(:include, target)
10
+ base
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -3,32 +3,31 @@ module Ecoportal
3
3
  module Common
4
4
  module Content
5
5
  module ModelHelpers
6
-
7
6
  private
8
7
 
9
8
  # Offers multiple ways to compare two strings
10
9
  # Offers multiple ways to compare two strings
11
- def same_string?(value1, value2, exact: false, mild: false)
12
- case
13
- when value1.is_a?(String) && value2.is_a?(String)
10
+ def same_string?(value_1, value_2, exact: false, mild: false)
11
+ if value_1.is_a?(String) && value_2.is_a?(String)
14
12
  if exact
15
- value1 == value2
13
+ value_1 == value_2
16
14
  else
17
- v1 = value1.to_s.strip.downcase
18
- v2 = value2.to_s.strip.downcase
15
+ v_1 = value_1.to_s.strip.downcase
16
+ v_2 = value_2.to_s.strip.downcase
19
17
 
20
18
  if mild
21
- v1 = v1.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
22
- v2 = v2.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
19
+ v_1 = v_1.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
20
+ v_2 = v_2.gsub(/[^a-z ]+/, ' ').gsub(/\s+/, ' ').strip
23
21
  end
24
- v1 == v2
22
+
23
+ v_1 == v_2
25
24
  end
26
- when value1.is_a?(Regexp) && value2.is_a?(String)
27
- value2 =~ value1
28
- when value1.is_a?(String) && value2.is_a?(Regexp)
29
- value1 =~ value2
25
+ elsif value_1.is_a?(Regexp) && value_2.is_a?(String)
26
+ value_2 =~ value_1
27
+ elsif value_1.is_a?(String) && value_2.is_a?(Regexp)
28
+ value_1 =~ value_2
30
29
  else
31
- value1 == value2
30
+ value_1 == value_2
32
31
  end
33
32
  end
34
33
 
@@ -36,7 +35,6 @@ module Ecoportal
36
35
  keys.each {|key| hash.delete(key)}
37
36
  hash
38
37
  end
39
-
40
38
  end
41
39
  end
42
40
  end
@@ -7,6 +7,7 @@ module Ecoportal
7
7
  end
8
8
  end
9
9
 
10
+ require 'ecoportal/api/common/content/includer'
10
11
  require 'ecoportal/api/common/content/class_helpers'
11
12
  require 'ecoportal/api/common/content/string_digest'
12
13
  require 'ecoportal/api/common/content/model_helpers'