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.
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, #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.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 100 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
Resolves to the nuclear Class of the elements
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 34 def klass(value = NOT_USED, &block) if block @klass = block block.call(value) if value != NOT_USED @klass elsif used_param?(value) if @klass.is_a?(Proc) @klass.call(value) else resolve_class(@klass, exception: false) end else resolve_class(@klass, exception: false) 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.
12 13 14 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 12 def order_key @order_key end |
.order_matters ⇒ Object
Returns the value of attribute order_matters.
12 13 14 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 12 def order_matters @order_matters end |
Class Method Details
.doc_class(name) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 88 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
16 17 18 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 16 def items_key @items_key ||= "id" end |
.items_key=(value) ⇒ Object
20 21 22 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 20 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?.
84 85 86 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 84 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
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 64 def new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false, &block) if block @new_item = block elsif used_param?(doc) raise "You should define either a 'klass' or a 'new_item' callback first" unless klass? if @new_item @new_item.call(doc, parent, key) else if target_class = self.klass(doc) doc.is_a?(target_class) ? doc : target_class.new(doc, parent: parent, key: key, read_only: read_only) else raise "Could not find a class for: #{doc}" end end else raise "To define the 'new_item' callback (factory), you need to use a block" end end |
Instance Method Details
#[](value) ⇒ Object
Get an element usign the key.
175 176 177 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 175 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
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 130 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
122 123 124 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 122 def _doc_pos(value) _doc_key(value) end |
#_items ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 162 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 end end |
#clear ⇒ Object
Deletes all the elements of this CollectionModel instance
215 216 217 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 215 def clear self.to_a.each {|item| delete!(item)} end |
#delete!(value) ⇒ Object
Deletes value from this CollectionModel instance
224 225 226 227 228 229 230 231 232 233 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 224 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
157 158 159 160 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 157 def each(&block) return to_enum(:each) unless block _items.each(&block) end |
#empty? ⇒ Boolean
154 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 154 def empty?; count == 0; end |
#include?(value) ⇒ Boolean
Checks if an element exists in the collection
182 183 184 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 182 def include?(value) items_by_key.key?(get_key(value)) end |
#items_class ⇒ Class
Returns the class of the elements of the Collection.
118 119 120 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 118 def items_class self.class.klass end |
#length ⇒ Object
153 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 153 def length; count; end |
#present? ⇒ Boolean
155 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 155 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
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 195 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.
187 188 189 |
# File 'lib/ecoportal/api/common/content/collection_model.rb', line 187 def values_at(*keys) keys.map {|key| self[key]} end |