Class: Volt::ArrayModel
- Inherits:
-
ReactiveArray
- Object
- ReactiveArray
- Volt::ArrayModel
- Defined in:
- lib/volt/models/array_model.rb
Direct Known Subclasses
Constant Summary
Constants included from Models::Helpers::Base
Models::Helpers::Base::ID_CHARS
Instance Attribute Summary collapse
-
#array ⇒ Object
readonly
Returns the value of attribute array.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#path ⇒ Object
Returns the value of attribute path.
-
#persistor ⇒ Object
readonly
Returns the value of attribute persistor.
Class Method Summary collapse
- .process_class_name(name) ⇒ Object
-
.proxy_to_persistor(*method_names) ⇒ Object
Some methods get passed down to the persistor.
-
.proxy_with_load(*method_names) ⇒ Object
For many methods, we want to register a dependency on the root_dep as soon as the method is called, so it can begin loading.
Instance Method Summary collapse
-
#+(*args) ⇒ Object
Make sure it gets wrapped.
-
#<<(model) ⇒ Object
Make sure it gets wrapped.
-
#all ⇒ Object
Return the model, on store, .all is proxied to wait for load and return a promise.
-
#append(model) ⇒ Object
Works like << except it always returns a promise.
- #attributes ⇒ Object
- #buffer(attrs = {}) ⇒ Object
- #count(&block) ⇒ Object
-
#create(model = {}) ⇒ Object
Create does append with a default empty model.
- #delete(val) ⇒ Object
-
#fail_not_found_if_nil(promise) ⇒ Object
Raise a RecordNotFoundException if the promise returns a nil.
-
#fetch_first(&block) ⇒ Object
returns a promise to fetch the first instance.
- #first ⇒ Object
-
#first! ⇒ Object
Same as first, except it returns a promise (even on page collection), and it fails with a RecordNotFoundException if no result is found.
-
#first_or_create ⇒ Object
Return the first item in the collection, or create one if one does not exist yet.
- #flatten(*args) ⇒ Object
-
#initialize(array = [], options = {}) ⇒ ArrayModel
constructor
A new instance of ArrayModel.
-
#inject(*args) ⇒ Object
Make sure it gets wrapped.
- #inspect ⇒ Object
- #last ⇒ Object
- #new_array_model(*args) ⇒ Object
- #new_model(*args) ⇒ Object (also: #new)
-
#reactive_array_append ⇒ Object
Alias append for use inside of child append.
- #reactive_count ⇒ Object
- #reverse ⇒ Object
-
#select ⇒ Object
Array#select, with reactive notification.
- #state_for(*args) ⇒ Object
-
#to_a ⇒ Object
Convert the model to an array all of the way down.
- #to_json ⇒ Object
Methods included from Models::Helpers::ArrayModel
Methods included from StateManager
Methods included from Models::Helpers::Base
#deep_unwrap, #event_added, #event_removed, #generate_id, included, #root, #self_attributes, #setup_persistor, #store
Methods included from ModelWrapper
Methods inherited from ReactiveArray
#==, #[], #[]=, #all?, #any?, #clear, #delete_at, #each, #empty?, #insert, #method_missing, #respond_to_missing?, #size
Methods included from Eventable
#on, #remove_listener, #trigger!
Constructor Details
#initialize(array = [], options = {}) ⇒ ArrayModel
Returns a new instance of ArrayModel.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/volt/models/array_model.rb', line 89 def initialize(array = [], = {}) @options = @persistor = setup_persistor([:persistor]) array = wrap_values(array) super(array) if @persistor @persistor.loaded else change_state_to(:loaded_state, :loaded, false) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Volt::ReactiveArray
Instance Attribute Details
#array ⇒ Object (readonly)
Returns the value of attribute array.
17 18 19 |
# File 'lib/volt/models/array_model.rb', line 17 def array @array end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
17 18 19 |
# File 'lib/volt/models/array_model.rb', line 17 def @options end |
#parent ⇒ Object
Returns the value of attribute parent.
17 18 19 |
# File 'lib/volt/models/array_model.rb', line 17 def parent @parent end |
#path ⇒ Object
Returns the value of attribute path.
17 18 19 |
# File 'lib/volt/models/array_model.rb', line 17 def path @path end |
#persistor ⇒ Object (readonly)
Returns the value of attribute persistor.
17 18 19 |
# File 'lib/volt/models/array_model.rb', line 17 def persistor @persistor end |
Class Method Details
.process_class_name(name) ⇒ Object
306 307 308 |
# File 'lib/volt/models/array_model.rb', line 306 def self.process_class_name(name) name.pluralize end |
.proxy_to_persistor(*method_names) ⇒ Object
Some methods get passed down to the persistor.
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/volt/models/array_model.rb', line 75 def self.proxy_to_persistor(*method_names) method_names.each do |method_name| define_method(method_name) do |*args, &block| if @persistor.respond_to?(method_name) @persistor.send(method_name, *args, &block) else fail "this model's persistance layer does not support #{method_name}, try using store" end end end end |
.proxy_with_load(*method_names) ⇒ Object
For many methods, we want to register a dependency on the root_dep as soon as the method is called, so it can begin loading. Also, some persistors need to have special loading logic (such as returning a promise instead of immediately returning). To accomplish this, we call the #run_once_loaded method on the persistor.
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/volt/models/array_model.rb', line 24 def self.proxy_with_load(*method_names) imethods = instance_methods(false) method_names.each do |method_name| # Sometimes we want to alias a method_missing method, so we use super # instead to call it, if its not defined locally. if imethods.include?(method_name) imethod = true old_method_name = :"__old_#{method_name}" alias_method(old_method_name, method_name) else imethod = false end define_method(method_name) do |*args, &block| if imethod call_orig = proc do |*args| send(old_method_name, *args) end else call_orig = proc do |*args| super(*args) end end # track on the root dep persistor.try(:root_dep).try(:depend) if persistor.respond_to?(:run_once_loaded) && !Volt.in_mode?(:no_model_promises) promise = persistor.run_once_loaded.then do # We are already loaded and the result is going to be wrapped Volt.run_in_mode(:no_model_promises) do call_orig.call(*args) end end if block promise = promise.then do |val| block.call(val) end end promise else call_orig.call(*args) end end end end |
Instance Method Details
#+(*args) ⇒ Object
Make sure it gets wrapped
232 233 234 235 |
# File 'lib/volt/models/array_model.rb', line 232 def +(*args) args = wrap_values(args) super(*args) end |
#<<(model) ⇒ Object
Make sure it gets wrapped
132 133 134 |
# File 'lib/volt/models/array_model.rb', line 132 def <<(model) create_new_model(model, :<<) end |
#all ⇒ Object
Return the model, on store, .all is proxied to wait for load and return a promise.
215 216 217 |
# File 'lib/volt/models/array_model.rb', line 215 def all self end |
#append(model) ⇒ Object
Works like << except it always returns a promise
139 140 141 |
# File 'lib/volt/models/array_model.rb', line 139 def append(model) create_new_model(model, :append) end |
#attributes ⇒ Object
120 121 122 |
# File 'lib/volt/models/array_model.rb', line 120 def attributes self end |
#buffer(attrs = {}) ⇒ Object
285 286 287 288 289 290 291 292 293 |
# File 'lib/volt/models/array_model.rb', line 285 def buffer(attrs = {}) model_path = [:path] + [:[]] model_klass = Volt::Model.class_at_path(model_path) = .merge(path: model_path, save_to: self, buffer: true).reject { |k, _| k.to_sym == :persistor } model = model_klass.new(attrs, ) model end |
#count(&block) ⇒ Object
311 312 313 |
# File 'lib/volt/models/array_model.rb', line 311 def count(&block) all.reactive_count(&block) end |
#create(model = {}) ⇒ Object
Create does append with a default empty model
144 145 146 |
# File 'lib/volt/models/array_model.rb', line 144 def create(model={}) create_new_model(model, :create) end |
#delete(val) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/volt/models/array_model.rb', line 149 def delete(val) # Check to make sure the models are allowed to be deleted if !val.is_a?(Model) # Not a model, return as a Promise super(val).then else val.can_delete?.then do |can_delete| if can_delete super(val) else Promise.new.reject("permissions did not allow delete for #{val.inspect}.") end end end end |
#fail_not_found_if_nil(promise) ⇒ Object
Raise a RecordNotFoundException if the promise returns a nil.
296 297 298 299 300 301 302 303 304 |
# File 'lib/volt/models/array_model.rb', line 296 def fail_not_found_if_nil(promise) promise.then do |val| if val val else raise RecordNotFoundException.new end end end |
#fetch_first(&block) ⇒ Object
returns a promise to fetch the first instance
220 221 222 223 |
# File 'lib/volt/models/array_model.rb', line 220 def fetch_first(&block) Volt.logger.warn('.fetch_first is deprecated in favor of .first') first end |
#first ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/volt/models/array_model.rb', line 165 def first if persistor.is_a?(Persistors::ArrayStore) limit(1)[0] else self[0] end end |
#first! ⇒ Object
Same as first, except it returns a promise (even on page collection), and it fails with a RecordNotFoundException if no result is found.
175 176 177 |
# File 'lib/volt/models/array_model.rb', line 175 def first! fail_not_found_if_nil(first) end |
#first_or_create ⇒ Object
Return the first item in the collection, or create one if one does not exist yet.
181 182 183 184 185 186 187 188 189 |
# File 'lib/volt/models/array_model.rb', line 181 def first_or_create first.then do |item| if item item else create end end end |
#flatten(*args) ⇒ Object
237 238 239 |
# File 'lib/volt/models/array_model.rb', line 237 def flatten(*args) wrap_values(to_a.flatten(*args)) end |
#inject(*args) ⇒ Object
Make sure it gets wrapped
226 227 228 229 |
# File 'lib/volt/models/array_model.rb', line 226 def inject(*args) args = wrap_values(args) super(*args) end |
#inspect ⇒ Object
273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/volt/models/array_model.rb', line 273 def inspect # Track on size @size_dep.depend str = "#<#{self.class}" # str += " state:#{loaded_state}" # str += " path:#{path.join('.')}" if path # str += " persistor:#{persistor.inspect}" if persistor str += " #{@array.inspect}>" str end |
#last ⇒ Object
191 192 193 |
# File 'lib/volt/models/array_model.rb', line 191 def last self[-1] end |
#new_array_model(*args) ⇒ Object
246 247 248 |
# File 'lib/volt/models/array_model.rb', line 246 def new_array_model(*args) Volt::ArrayModel.class_at_path([:path]).new(*args) end |
#new_model(*args) ⇒ Object Also known as: new
241 242 243 |
# File 'lib/volt/models/array_model.rb', line 241 def new_model(*args) Volt::Model.class_at_path([:path]).new(*args) end |
#reactive_array_append ⇒ Object
Alias append for use inside of child append
137 |
# File 'lib/volt/models/array_model.rb', line 137 alias_method :reactive_array_append, :append |
#reactive_count ⇒ Object
310 |
# File 'lib/volt/models/array_model.rb', line 310 alias_method :reactive_count, :count |
#reverse ⇒ Object
195 196 197 198 |
# File 'lib/volt/models/array_model.rb', line 195 def reverse @size_dep.depend @array.reverse end |
#select ⇒ Object
Array#select, with reactive notification
201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/volt/models/array_model.rb', line 201 def select new_array = [] @array.size.times do |index| value = @array[index] if yield(value) new_array << value end end new_array end |
#state_for(*args) ⇒ Object
124 125 126 127 128 129 |
# File 'lib/volt/models/array_model.rb', line 124 def state_for(*args) # Track on root dep persistor.try(:root_dep).try(:depend) super end |
#to_a ⇒ Object
Convert the model to an array all of the way down
251 252 253 254 255 256 257 258 259 260 |
# File 'lib/volt/models/array_model.rb', line 251 def to_a @size_dep.depend array = [] Volt.run_in_mode(:no_model_promises) do attributes.size.times do |index| array << deep_unwrap(self[index]) end end array end |