Class: Ecoportal::API::Common::Content::CollectionModel
- Inherits:
-
DoubleModel
- Object
- Common::BaseModel
- DoubleModel
- Ecoportal::API::Common::Content::CollectionModel
- Includes:
- Enumerable
- Defined in:
- lib/ecoportal/api/common/content/collection_model.rb
Overview
to be able to refer to the correct element of the Collection,
it is required that those elements have a unique key that allows to identify them
CollectionModel aims to deal with Arrays of actual objects.
Direct Known Subclasses
V2::Page::Component::SelectionOptions, V2::Page::Components, V2::Page::Force::Bindings, V2::Page::Forces, V2::Page::Sections, V2::Page::Stages
Constant Summary
Constants inherited from DoubleModel
Constants included from ClassHelpers
Ecoportal::API::Common::Content::ClassHelpers::NOT_USED
Class Attribute Summary collapse
-
.klass(value = NOT_USED) {|doc| ... } ⇒ Klass
Resolves to the nuclear
Classof the elements. -
.order_key ⇒ Object
Returns the value of attribute order_key.
-
.order_matters ⇒ Object
Returns the value of attribute order_matters.
Attributes inherited from DoubleModel
Class Method Summary collapse
- .doc_class(name) ⇒ Object
-
.items_key ⇒ Object
The attr that has been defined as
passkeyin the item class. - .items_key=(value) ⇒ Object
-
.klass? ⇒ Boolean
Are there the factory logics to build item objects defined?.
-
.new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false) {|doc, parent, key| ... } ⇒ Klass
Generates a new object of the target class.
-
.new_item_class_based? ⇒ Boolean
Optimization.
Instance Method Summary collapse
-
#[](value) ⇒ Object
Get an element usign the
key. -
#_doc_key(value) ⇒ Object
Transforms
valueinto the actualkeyto access the object in the docArray. - #_doc_pos(value) ⇒ Object
- #_items ⇒ Object
-
#clear ⇒ Object
Deletes all the elements of this
CollectionModelinstance. -
#delete!(value) ⇒ Object
Deletes
valuefrom thisCollectionModelinstance. - #each(&block) ⇒ Object
- #empty? ⇒ Boolean
-
#include?(value) ⇒ Boolean
Checks if an element exists in the collection.
-
#initialize(ini_doc = [], parent: self, key: nil, read_only: false) ⇒ CollectionModel
constructor
A new instance of CollectionModel.
-
#items_class ⇒ Class
The class of the elements of the Collection.
- #length ⇒ Object
- #present? ⇒ Boolean
-
#upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED) ⇒ Object
Tries to find the element
value, if it exists, it updates it Otherwise it pushes it to the end. -
#values_at(*keys) ⇒ Array<Object>
The
items_classelement object.
Methods inherited from DoubleModel
#as_json, #as_update, #consolidate!, #dirty?, #doc, embeds_many, embeds_one, enforce!, #key, #key=, key?, new_uuid, #original_doc, pass_reader, pass_writer, passarray, passboolean, passdate, passforced, passkey, passthrough, #print_pretty, read_only!, read_only?, #read_only?, #replace_doc, #reset!, #root, #to_json
Methods included from ClassHelpers
#inheritable_attrs, #inheritable_class_vars, #inherited, #instance_variable_name, #new_class, #resolve_class, #to_constant, #to_time, #uid, #used_param?
Constructor Details
#initialize(ini_doc = [], parent: self, key: nil, read_only: false) ⇒ CollectionModel
Returns a new instance of CollectionModel.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 107 def initialize(ini_doc = [], parent: self, key: nil, read_only: false) unless self.class.klass? raise "Undefined base 'klass' or 'new_item' callback for #{self.class}" end ini_doc = case ini_doc when Array ini_doc when Enumerable ini_doc.to_a else [] end super(ini_doc, parent: parent, key: key, read_only: read_only) end |
Class Attribute Details
.klass(value = NOT_USED) {|doc| ... } ⇒ Klass
- use block to define
klasscallback
When klass is resolved, if the items are of type
DoubleModel, it sets on the collection class the items_key
when klass is directly resolved (not via doc) only once
it will set @klass as resolved and will use this class from now on.
This is an optimization to cut class lookups
Resolves to the nuclear Class of the elements
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 36 def klass(value = NOT_USED, &block) @klass = block if block_given? if @klass && !@class.is_a?(Proc) @klass = resolve_class(@klass, exception: false) unless @klass.is_a?(Class) @klass elsif @klass.is_a?(Proc) && used_param?(value) @klass.call(value) else @klass end.tap do |result| next unless result.is_a?(Class) next unless result < Ecoportal::API::Common::Content::DoubleModel self.items_key = result.key end end |
.order_key ⇒ Object
Returns the value of attribute order_key.
11 12 13 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 11 def order_key @order_key end |
.order_matters ⇒ Object
Returns the value of attribute order_matters.
11 12 13 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 11 def order_matters @order_matters end |
Class Method Details
.doc_class(name) ⇒ Object
95 96 97 98 99 100 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 95 def doc_class(name) dim_class = new_class(name, inherits: Common::Content::ArrayModel) do |klass| klass.order_matters = order_matters klass.uniq = uniq end end |
.items_key ⇒ Object
The attr that has been defined as passkey
in the item class
15 16 17 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 15 def items_key @items_key ||= "id" end |
.items_key=(value) ⇒ Object
19 20 21 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 19 def items_key=(value) @items_key = value && value.to_s.freeze end |
.klass? ⇒ Boolean
Returns are there the factory logics to build item objects defined?.
54 55 56 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 54 def klass? @klass || @new_item end |
.new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false) {|doc, parent, key| ... } ⇒ Klass
- use block to define
new_itemcallback, which will prevail overklass - if
new_itemcallback was not defined, it is required to defnieklass
if block is given, it ignores doc
Generates a new object of the target class
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 80 def new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false, &block) return (@new_item = block; nil) if block_given msg = "To define the 'new_item' callback (factory), you need to use a block" raise msg unless used_param?(doc) msg = "You should define either a 'klass' or a 'new_item' callback first" raise msg unless klass? return @new_item.call(doc, parent, key) if @new_item.is_a?(Proc) raise "Could not find a class for: #{doc}" unless target_class = klass(doc) return doc if doc.is_a?(target_class) target_class.new(doc, parent: parent, key: key, read_only: read_only) end |
.new_item_class_based? ⇒ Boolean
Optimization
59 60 61 62 63 64 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 59 def new_item_class_based? return false if @new_item.is_a?(Proc) return false if @klass.is_a?(Proc) return true if klass.is_a?(Class) false end |
Instance Method Details
#[](value) ⇒ Object
Get an element usign the key.
183 184 185 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 183 def [](value) items_by_key[get_key(value)] end |
#_doc_key(value) ⇒ Object
- The name of the method is after the paren't class method
- This method would have been better called
_doc_pos:)
Transforms value into the actual key to access the object in the doc Array
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 137 def _doc_key(value) #print "*(#{value.class})" return super(value) unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel) if id = get_key(value) #print "^" _doc_items.index {|item| get_key(item) == id}.tap do |p| #print "{{#{p}}}" end else show_str = \ case value when Hash value.pretty_inspect when Content::DoubleModel "#{value} with key: #{value.class.key} (items_key: #{self.class.items_key})" else value end raise UnlinkedModel, "Can't find child: #{show_str}" end end |
#_doc_pos(value) ⇒ Object
129 130 131 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 129 def _doc_pos(value) _doc_key(value) end |
#_items ⇒ Object
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 169 def _items return @_items if @_items [].tap do |elements| variable_set(:@_items, elements) _doc_items.each do |item_doc| elements << new_item(item_doc) end @_items = elements if read_only? end end |
#clear ⇒ Object
Deletes all the elements of this CollectionModel instance
223 224 225 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 223 def clear self.to_a.each {|item| delete!(item)} end |
#delete!(value) ⇒ Object
Deletes value from this CollectionModel instance
232 233 234 235 236 237 238 239 240 241 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 232 def delete!(value) unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel) || value.is_a?(String) raise "'Content::DoubleModel' or 'Hash' doc required" end if item = self[value] _doc_delete(item.doc) @indexed = false _items.delete(item) end end |
#each(&block) ⇒ Object
164 165 166 167 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 164 def each(&block) return to_enum(:each) unless block _items.each(&block) end |
#empty? ⇒ Boolean
161 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 161 def empty?; count == 0; end |
#include?(value) ⇒ Boolean
Checks if an element exists in the collection
190 191 192 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 190 def include?(value) items_by_key.key?(get_key(value)) end |
#items_class ⇒ Class
Returns the class of the elements of the Collection.
125 126 127 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 125 def items_class self.class.klass end |
#length ⇒ Object
160 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 160 def length; count; end |
#present? ⇒ Boolean
162 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 162 def present?; count > 0; end |
#upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED) ⇒ Object
Tries to find the element value, if it exists, it updates it
Otherwise it pushes it to the end
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 203 def upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED) unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel) raise "'Content::DoubleModel' or 'Hash' doc required. Given #{value.class}" end item_doc = value.is_a?(Content::DoubleModel)? value.doc : value item_doc = JSON.parse(item_doc.to_json) if item = self[value] item.replace_doc(item_doc) else _doc_upsert(item_doc, pos: pos, before: before, after: after).tap do |pos_idx| _items.insert(pos_idx, new_item(item_doc)) @indexed = false end end (item || self[item_doc]).tap do |item| yield(item) if block_given? end end |
#values_at(*keys) ⇒ Array<Object>
Returns the items_class element object.
195 196 197 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 195 def values_at(*keys) keys.map {|key| self[key]} end |