hyper-mesh 1.0.0.lap27 → 1.0.0.lap28

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +6 -2
  4. data/Gemfile +0 -1
  5. data/Rakefile +2 -2
  6. data/hyper-mesh.gemspec +1 -1
  7. data/lib/active_record_base.rb +39 -27
  8. data/lib/hyper-mesh.rb +6 -1
  9. data/lib/hypermesh/version.rb +1 -1
  10. data/lib/object/tap.rb +7 -0
  11. data/lib/reactive_record/active_record/associations.rb +14 -3
  12. data/lib/reactive_record/active_record/base.rb +1 -2
  13. data/lib/reactive_record/active_record/class_methods.rb +120 -67
  14. data/lib/reactive_record/active_record/error.rb +17 -12
  15. data/lib/reactive_record/active_record/errors.rb +374 -0
  16. data/lib/reactive_record/active_record/instance_methods.rb +58 -67
  17. data/lib/reactive_record/active_record/reactive_record/backing_record_inspector.rb +1 -4
  18. data/lib/reactive_record/active_record/reactive_record/base.rb +129 -234
  19. data/lib/reactive_record/active_record/reactive_record/collection.rb +51 -18
  20. data/lib/reactive_record/active_record/reactive_record/column_types.rb +5 -3
  21. data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +6 -4
  22. data/lib/reactive_record/active_record/reactive_record/getters.rb +133 -0
  23. data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +99 -87
  24. data/lib/reactive_record/active_record/reactive_record/lookup_tables.rb +54 -0
  25. data/lib/reactive_record/active_record/reactive_record/operations.rb +2 -1
  26. data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +1 -1
  27. data/lib/reactive_record/active_record/reactive_record/setters.rb +194 -0
  28. data/lib/reactive_record/active_record/reactive_record/while_loading.rb +4 -5
  29. data/lib/reactive_record/active_record_error.rb +4 -0
  30. data/lib/reactive_record/broadcast.rb +55 -18
  31. data/lib/reactive_record/permissions.rb +5 -4
  32. data/lib/reactive_record/scope_description.rb +14 -6
  33. data/lib/reactive_record/server_data_cache.rb +119 -70
  34. metadata +16 -13
  35. data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +0 -189
@@ -7,7 +7,7 @@ module ReactiveRecord
7
7
  return error_details unless errors.empty?
8
8
  return new_details if new?
9
9
  return destroyed_details if destroyed
10
- return loading_details unless attributes.key? primary_key
10
+ return loading_details unless @attributes.key? primary_key
11
11
  return dirty_details unless changed_attributes.empty?
12
12
  "[loaded id: #{id}]"
13
13
  end
@@ -30,9 +30,6 @@ module ReactiveRecord
30
30
  end
31
31
 
32
32
  def dirty_details
33
- changes = Hash[changed_attributes.collect do |attr|
34
- [attr, [@synced_attributes[attr], attributes[attr]]] if column_type(attr)
35
- end.compact]
36
33
  "[changed id: #{id} #{changes}]"
37
34
  end
38
35
  end
@@ -1,6 +1,9 @@
1
1
  module ReactiveRecord
2
2
  class Base
3
3
  include BackingRecordInspector
4
+ include Setters
5
+ include Getters
6
+ extend LookupTables
4
7
 
5
8
  # Its all about lazy loading. This prevents us from grabbing enormous association collections, or large attributes
6
9
  # unless they are explicitly requested.
@@ -8,7 +11,8 @@ module ReactiveRecord
8
11
  # During prerendering we get each attribute as its requested and fill it in both on the javascript side, as well as
9
12
  # remember that the attribute needs to be part of the download to client.
10
13
 
11
- # On the client we fill in the record data with empty values (nil, or one element collections) but only as the attribute
14
+ # On the client we fill in the record data with empty values (the default value for the attribute,
15
+ # or one element collections) but only as the attribute
12
16
  # is requested. Each request queues up a request to get the real data from the server.
13
17
 
14
18
  # The ReactiveRecord class serves two purposes. First it is the unique data corresponding to the last known state of a
@@ -37,9 +41,10 @@ module ReactiveRecord
37
41
  attr_accessor :updated_during
38
42
  attr_accessor :synced_attributes
39
43
  attr_accessor :virgin
44
+ attr_reader :attributes
40
45
 
41
46
  # While data is being loaded from the server certain internal behaviors need to change
42
- # for example records all record changes are synced as they happen.
47
+ # for example all record changes are synced as they happen.
43
48
  # This is implemented this way so that the ServerDataCache class can use pure active
44
49
  # record methods in its implementation
45
50
 
@@ -62,44 +67,48 @@ module ReactiveRecord
62
67
  load_data { ServerDataCache.load_from_json(json, target) }
63
68
  end
64
69
 
65
- def self.class_scopes(model)
66
- @class_scopes[model.base_class]
67
- end
68
-
69
- # def self.sync_blocks
70
- # # @sync_blocks[watch_model][sync_model][scope_name][...array of blocks...]
71
- # @sync_blocks ||= Hash.new { |hash, key| hash[key] = Hash.new { |hash, key| hash[key] = Hash.new { |hash, key| hash[key] = [] } } }
72
- # end
73
-
74
-
75
- def self.find(model, attribute, value)
70
+ def self.find(model, attrs)
76
71
  # will return the unique record with this attribute-value pair
77
72
  # value cannot be an association or aggregation
78
73
 
74
+ # add the inheritance column if this is an STI subclass
75
+
76
+ inher_col = model.inheritance_column
77
+ if inher_col && model < model.base_class && !attrs.key?(inher_col)
78
+ attrs = attrs.merge(inher_col => model.model_name)
79
+ end
80
+
79
81
  model = model.base_class
80
- # already have a record with this attribute-value pair?
81
- record = @records[model].detect { |record| record.attributes[attribute] == value}
82
+ primary_key = model.primary_key
83
+
84
+ # already have a record with these attribute-value pairs?
85
+
86
+ record =
87
+ if (id_to_find = attrs[primary_key])
88
+ lookup_by_id(model, id_to_find)
89
+ else
90
+ @records[model].detect do |r|
91
+ !attrs.detect { |attr, value| r.synced_attributes[attr] != value }
92
+ end
93
+ end
94
+
82
95
  unless record
83
96
  # if not, and then the record may be loaded, but not have this attribute set yet,
84
97
  # so find the id of of record with the attribute-value pair, and see if that is loaded.
85
98
  # find_in_db returns nil if we are not prerendering which will force us to create a new record
86
99
  # because there is no way of knowing the id.
87
- if attribute != model.primary_key and id = find_in_db(model, attribute, value)
88
- record = @records[model].detect { |record| record.id == id}
100
+ if !attrs.key?(primary_key) && (id = find_in_db(model, attrs))
101
+ record = lookup_by_id(model, id) # @records[model].detect { |record| record.id == id}
102
+ attrs = attrs.merge primary_key => id
89
103
  end
90
104
  # if we don't have a record then create one
91
- (record = new(model)).vector = [model, [:find_by, attribute => value]] unless record
92
- # and set the value
93
- record.sync_attribute(attribute, value)
94
- # and set the primary if we have one
95
- record.sync_attribute(model.primary_key, id) if id
105
+ # (record = new(model)).vector = [model, [:find_by, attribute => value]] unless record
106
+ record ||= set_vector_lookup(new(model), [model, [:find_by, attrs]])
107
+ # and set the values
108
+ attrs.each { |attr, value| record.sync_attribute(attr, value) }
96
109
  end
97
110
  # finally initialize and return the ar_instance
98
- record.ar_instance ||= infer_type_from_hash(model, record.attributes).new(record)
99
- end
100
-
101
- def self.find_by_object_id(model, object_id)
102
- @records[model].detect { |record| record.object_id == object_id }.ar_instance
111
+ record.set_ar_instance!
103
112
  end
104
113
 
105
114
  def self.new_from_vector(model, aggregate_owner, *vector)
@@ -110,13 +119,15 @@ module ReactiveRecord
110
119
 
111
120
  # do we already have a record with this vector? If so return it, otherwise make a new one.
112
121
 
113
- record = @records[model].detect { |record| record.vector == vector }
122
+ # record = @records[model].detect { |record| record.vector == vector }
123
+ record = lookup_by_vector(vector)
114
124
  unless record
125
+
115
126
  record = new model
116
- record.vector = vector
127
+ set_vector_lookup(record, vector)
117
128
  end
118
129
 
119
- record.ar_instance ||= infer_type_from_hash(model, record.attributes).new(record)
130
+ record.set_ar_instance!
120
131
 
121
132
  if aggregate_owner
122
133
  record.aggregate_owner = aggregate_owner
@@ -125,7 +136,6 @@ module ReactiveRecord
125
136
  end
126
137
 
127
138
  record.ar_instance
128
-
129
139
  end
130
140
 
131
141
  def initialize(model, hash = {}, ar_instance = nil)
@@ -136,6 +146,7 @@ module ReactiveRecord
136
146
  @changed_attributes = []
137
147
  @virgin = true
138
148
  records[model] << self
149
+ Base.set_object_id_lookup(self)
139
150
  end
140
151
 
141
152
  def find(*args)
@@ -151,13 +162,15 @@ module ReactiveRecord
151
162
  end
152
163
 
153
164
  def id
154
- attributes[primary_key]
165
+ @attributes[primary_key]
155
166
  end
156
167
 
157
168
  def id=(value)
158
169
  # value can be nil if we are loading an aggregate otherwise check if it already exists
159
- if !(value and existing_record = records[@model].detect { |record| record.attributes[primary_key] == value})
160
- attributes[primary_key] = value
170
+ # if !(value && (existing_record = records[@model].detect { |record| record.attributes[primary_key] == value}))
171
+ if !(value && (existing_record = Base.lookup_by_id(model, value)))
172
+ @attributes[primary_key] = value
173
+ Base.set_id_lookup(self)
161
174
  else
162
175
  @ar_instance.instance_variable_set(:@backing_record, existing_record)
163
176
  existing_record.attributes.merge!(attributes) { |key, v1, v2| v1 }
@@ -165,85 +178,6 @@ module ReactiveRecord
165
178
  value
166
179
  end
167
180
 
168
- def attributes
169
- @last_access_at = Time.now
170
- @attributes
171
- end
172
-
173
- def reactive_get!(attribute, reload = nil)
174
- @virgin = false unless data_loading?
175
- unless @destroyed
176
- if @attributes.has_key? attribute
177
- attributes[attribute].notify if @attributes[attribute].is_a? DummyValue
178
- apply_method(attribute) if reload
179
- else
180
- apply_method(attribute)
181
- end
182
- React::State.get_state(self, attribute) unless data_loading?
183
- attributes[attribute]
184
- end
185
- end
186
-
187
- def reactive_set!(attribute, value)
188
- @virgin = false unless data_loading?
189
- return value if @destroyed || dont_update_attribute?(attribute, value)
190
- return attributes[attribute] if update_aggregate(attribute, value)
191
- value = update_relationships(attribute, value)
192
- update_attribute(attribute, value)
193
- value
194
- end
195
-
196
- def dont_update_attribute?(attribute, value)
197
- return false if attributes[attribute].is_a?(DummyValue)
198
- return false unless attributes.key?(attribute)
199
- return false if attributes[attribute] != value
200
- true
201
- end
202
-
203
- def update_attribute(attribute, *args)
204
- value = args[0]
205
- if args.count != 0 and data_loading?
206
- if (aggregation = model.reflect_on_aggregation(attribute)) and !(aggregation.klass < ActiveRecord::Base)
207
- @synced_attributes[attribute] = aggregation.deserialize(aggregation.serialize(value))
208
- else
209
- @synced_attributes[attribute] = value
210
- end
211
- end
212
- if @virgin
213
- attributes[attribute] = value if args.count != 0
214
- return
215
- end
216
- changed = if args.count == 0
217
- if (association = @model.reflect_on_association(attribute)) and association.collection?
218
- attributes[attribute] != @synced_attributes[attribute]
219
- else
220
- !attributes[attribute].backing_record.changed_attributes.empty?
221
- end
222
- elsif (association = @model.reflect_on_association(attribute)) and association.collection?
223
- value != @synced_attributes[attribute]
224
- else
225
- !@synced_attributes.has_key?(attribute) or @synced_attributes[attribute] != value
226
- end
227
- empty_before = changed_attributes.empty?
228
- if !changed
229
- changed_attributes.delete(attribute)
230
- elsif !changed_attributes.include?(attribute)
231
- changed_attributes << attribute
232
- end
233
- had_key = attributes.has_key? attribute
234
- current_value = attributes[attribute]
235
- attributes[attribute] = value if args.count != 0
236
- if !data_loading?
237
- React::State.set_state(self, attribute, value)
238
- elsif on_opal_client? and had_key and current_value.loaded? and current_value != value and args.count > 0 # this is to handle changes in already loaded server side methods
239
- React::State.set_state(self, attribute, value, true)
240
- end
241
- if empty_before != changed_attributes.empty?
242
- React::State.set_state(self, "!CHANGED!", !changed_attributes.empty?, true) unless on_opal_server? or data_loading?
243
- aggregate_owner.update_attribute(aggregate_attribute) if aggregate_owner
244
- end
245
- end
246
-
247
181
  def changed?(*args)
248
182
  if args.count == 0
249
183
  React::State.get_state(self, "!CHANGED!")
@@ -254,20 +188,34 @@ module ReactiveRecord
254
188
  end
255
189
  end
256
190
 
191
+ def changed_attributes_and_values
192
+ Hash[changed_attributes.collect do |attr|
193
+ [attr, @attributes[attr]] if column_type(attr)
194
+ end.compact]
195
+ end
196
+
197
+ def changes
198
+ Hash[changed_attributes.collect do |attr|
199
+ [attr, [@synced_attributes[attr], @attributes[attr]]] if column_type(attr)
200
+ end.compact]
201
+ end
202
+
257
203
  def errors
258
- @errors ||= ActiveModel::Error.new
204
+ @errors ||= ActiveModel::Errors.new(self)
259
205
  end
260
206
 
261
207
  # called when we have a newly created record, to initialize
262
208
  # any nil collections to empty arrays. We can do this because
263
209
  # if its a brand new record, then any collections that are still
264
210
  # nil must not have any children.
211
+
265
212
  def initialize_collections
266
213
  if (!vector || vector.empty?) && id && id != ''
267
- @vector = [@model, [:find_by, @model.primary_key => id]]
214
+ Base.set_vector_lookup(self, [@model, [:find_by, @model.primary_key => id]])
268
215
  end
269
- @model.reflect_on_all_associations.each do |assoc|
270
- if assoc.collection? && attributes[assoc.attribute].nil?
216
+ Base.load_data do
217
+ @model.reflect_on_all_associations.each do |assoc|
218
+ next if !assoc.collection? || @attributes[assoc.attribute]
271
219
  ar_instance.send("#{assoc.attribute}=", [])
272
220
  end
273
221
  end
@@ -275,14 +223,14 @@ module ReactiveRecord
275
223
 
276
224
  # sync! now will also initialize any nil collections
277
225
  def sync!(hash = {}) # does NOT notify (see saved! for notification)
278
- hash.each do |attr, value|
279
- @attributes[attr] = convert(attr, value)
280
- end
226
+ # hash.each do |attr, value|
227
+ # @attributes[attr] = convert(attr, value)
228
+ # end
281
229
  @synced_attributes = {}
282
- @synced_attributes.each { |attribute, value| sync_attribute(key, value) }
230
+ hash.each { |attr, value| sync_attribute(attr, convert(attr, value)) }
283
231
  @changed_attributes = []
284
232
  @saving = false
285
- @errors = nil
233
+ errors.clear
286
234
  # set the vector and clear collections - this only happens when a new record is saved
287
235
  initialize_collections if (!vector || vector.empty?) && id && id != ''
288
236
  self
@@ -305,7 +253,8 @@ module ReactiveRecord
305
253
 
306
254
  def sync_attribute(attribute, value)
307
255
 
308
- @synced_attributes[attribute] = attributes[attribute] = value
256
+ @synced_attributes[attribute] = @attributes[attribute] = value
257
+ Base.set_id_lookup(self) if attribute == primary_key
309
258
 
310
259
  #@synced_attributes[attribute] = value.dup if value.is_a? ReactiveRecord::Collection
311
260
 
@@ -326,7 +275,7 @@ module ReactiveRecord
326
275
  # helper so we can tell if model exists. We need this so we can detect
327
276
  # if a record has local changes that are out of sync.
328
277
  def self.exists?(model, id)
329
- @records[model].detect { |record| record.attributes[model.primary_key] == id }
278
+ Base.lookup_by_id(model, id)
330
279
  end
331
280
 
332
281
  def revert
@@ -335,7 +284,7 @@ module ReactiveRecord
335
284
  @attributes.delete(attribute) unless @synced_attributes.key?(attribute)
336
285
  end
337
286
  @changed_attributes = []
338
- @errors = nil
287
+ errors.clear
339
288
  end
340
289
 
341
290
  def saving!
@@ -343,14 +292,20 @@ module ReactiveRecord
343
292
  @saving = true
344
293
  end
345
294
 
346
- def errors!(errors)
347
- @saving = false
348
- @errors = errors && ActiveModel::Error.new(errors)
295
+ def errors!(hash)
296
+ notify_waiting_for_save
297
+ errors.clear && return unless hash
298
+ hash.each do |attribute, messages|
299
+ messages.each do |message|
300
+ errors.add(attribute, message: message)
301
+ end
302
+ end
349
303
  end
350
304
 
351
- def saved! # sets saving to false AND notifies
352
- @saving = false
353
- if !@errors or @errors.empty?
305
+ def saved!(save_only = nil) # sets saving to false AND notifies
306
+ notify_waiting_for_save
307
+ return self if save_only
308
+ if errors.empty?
354
309
  React::State.set_state(self, self, :saved)
355
310
  elsif !data_loading?
356
311
  React::State.set_state(self, self, :error)
@@ -358,6 +313,26 @@ module ReactiveRecord
358
313
  self
359
314
  end
360
315
 
316
+ def self.when_not_saving(model, &block)
317
+ if @records[model].detect(&:saving?)
318
+ wait_for_save(model, &block)
319
+ else
320
+ yield model
321
+ end
322
+ end
323
+
324
+ def notify_waiting_for_save
325
+ @saving = false
326
+ self.class.notify_waiting_for_save(model)
327
+ end
328
+
329
+ def self.notify_waiting_for_save(model)
330
+ waiters = waiting_for_save(model)
331
+ return if waiters.empty? || @records[model].detect(&:saving?)
332
+ waiters.each { |waiter| waiter.call model }
333
+ clear_waiting_for_save(model)
334
+ end
335
+
361
336
  def saving?
362
337
  React::State.get_state(self, self)
363
338
  @saving
@@ -367,88 +342,26 @@ module ReactiveRecord
367
342
  !id && !vector
368
343
  end
369
344
 
370
- def find_association(association, id)
371
- inverse_of = association.inverse_of
372
- instance = if id
373
- find(association.klass, association.klass.primary_key, id)
374
- else
375
- new_from_vector(association.klass, nil, *vector, association.attribute)
376
- end
377
- instance_backing_record_attributes = instance.backing_record.attributes
378
- inverse_association = association.klass.reflect_on_association(inverse_of)
379
- if inverse_association.collection?
380
- instance_backing_record_attributes[inverse_of] = if id and id != ""
381
- Collection.new(@model, instance, inverse_association, association.klass, ["find", id], inverse_of)
382
- else
383
- Collection.new(@model, instance, inverse_association, *vector, association.attribute, inverse_of)
384
- end unless instance_backing_record_attributes[inverse_of]
385
- instance_backing_record_attributes[inverse_of].replace [@ar_instance]
386
- else
387
- instance_backing_record_attributes[inverse_of] = @ar_instance
388
- end unless association.through_association? || instance_backing_record_attributes.key?(inverse_of)
389
- instance
390
- end
391
-
392
- def apply_method(method)
393
- # Fills in the value returned by sending "method" to the corresponding server side db instance
394
- if on_opal_server? and changed?
395
- log("Warning fetching virtual attributes (#{model.name}.#{method}) during prerendering on a changed or new model is not implemented.", :warning)
396
- # to implement this we would have to sync up any changes during prererendering with a set the cached models (see server_data_cache)
397
- # right now server_data cache is read only, BUT we could change this. However it seems like a tails case. Why would we create or update
398
- # a model during prerendering???
399
- end
400
- if !new?
401
- new_value = if association = @model.reflect_on_association(method)
402
- if association.collection?
403
- Collection.new(association.klass, @ar_instance, association, *vector, method)
404
- else
405
- find_association(association, (id and id != "" and self.class.fetch_from_db([@model, [:find, id], method, @model.primary_key])))
406
- end
407
- elsif aggregation = @model.reflect_on_aggregation(method) and (aggregation.klass < ActiveRecord::Base)
408
- new_from_vector(aggregation.klass, self, *vector, method)
409
- elsif id and id != ''
410
- self.class.fetch_from_db([@model, [:find, id], *method]) || self.class.load_from_db(self, *(vector ? vector : [nil]), method)
411
- else # its a attribute in an aggregate or we are on the client and don't know the id
412
- self.class.fetch_from_db([*vector, *method]) || self.class.load_from_db(self, *(vector ? vector : [nil]), method)
413
- end
414
- new_value = @attributes[method] if new_value.is_a? DummyValue and @attributes.has_key?(method)
415
- sync_attribute(method, new_value)
416
- elsif association = @model.reflect_on_association(method) and association.collection?
417
- @attributes[method] = Collection.new(association.klass, @ar_instance, association)
418
- elsif aggregation = @model.reflect_on_aggregation(method) and (aggregation.klass < ActiveRecord::Base)
419
- @attributes[method] = aggregation.klass.new.tap do |aggregate|
420
- backing_record = aggregate.backing_record
421
- backing_record.aggregate_owner = self
422
- backing_record.aggregate_attribute = method
423
- end
424
- elsif !aggregation and method != model.primary_key
425
- if model.columns_hash[method]
426
- new_value = convert(method, model.columns_hash[method][:default])
427
- else
428
- unless @attributes.key?(method)
429
- log("Warning: reading from new #{model.name}.#{method} before assignment. Will fetch value from server. This may not be what you expected!!", :warning)
430
- end
431
- new_value = self.class.load_from_db(self, *(vector ? vector : [nil]), method)
432
- new_value = @attributes[method] if new_value.is_a?(DummyValue) && @attributes.key?(method)
433
- end
434
- sync_attribute(method, new_value)
435
- end
436
- end
437
-
438
- def self.infer_type_from_hash(klass, hash)
439
- klass = klass.base_class
440
- return klass unless hash
441
- type = hash[klass.inheritance_column]
442
- begin
443
- return Object.const_get(type)
444
- rescue Exception => e
445
- message = "Could not subclass #{@model_klass.model_name} as #{type}. Perhaps #{type} class has not been required. Exception: #{e}"
446
- `console.error(#{message})`
447
- end if type
448
- klass
345
+ def set_ar_instance!
346
+ klass = self.class.infer_type_from_hash(model, @attributes)
347
+ @ar_instance = klass._new_without_sti_type_cast(self) unless @ar_instance.class == klass
348
+ @ar_instance
449
349
  end
450
350
 
451
351
  class << self
352
+ def infer_type_from_hash(klass, hash)
353
+ klass = klass.base_class
354
+ return klass unless hash
355
+ type = hash[klass.inheritance_column]
356
+ begin
357
+ return Object.const_get(type)
358
+ rescue Exception => e
359
+ message = "Could not subclass #{klass} as #{type}. Perhaps #{type} class has not been required. Exception: #{e}"
360
+ `console.error(#{message})`
361
+ end unless !type || type == ''
362
+ klass
363
+ end
364
+
452
365
  attr_reader :outer_scopes
453
366
 
454
367
  def default_scope
@@ -462,36 +375,19 @@ module ReactiveRecord
462
375
  def add_to_outer_scopes(item)
463
376
  @outer_scopes << item
464
377
  end
465
- end
466
378
 
467
- # when_not_saving will wait until reactive-record is not saving a model.
468
- # Currently there is no easy way to do this without polling.
469
- def self.when_not_saving(model)
470
- if @records[model].detect(&:saving?)
471
- poller = every(0.1) do
472
- unless @records[model].detect(&:saving?)
473
- poller.stop
474
- yield model
475
- end
476
- end
477
- else
478
- yield model
479
- end
480
- end
481
-
482
- # While evaluating scopes we want to catch any requests
483
- # to the server. Once we catch any requests to the server
484
- # then all the further scopes in that chain will be made
485
- # at the server.
379
+ # While evaluating scopes we want to catch any requests
380
+ # to the server. Once we catch any requests to the server
381
+ # then all the further scopes in that chain will be made
382
+ # at the server.
486
383
 
487
- class << self
488
384
  class DbRequestMade < RuntimeError; end
489
385
 
490
386
  def catch_db_requests(return_val = nil)
491
387
  @catch_db_requests = true
492
388
  yield
493
389
  rescue DbRequestMade => e
494
- puts "Warning request for server side data during scope evaluation: #{e.message}"
390
+ React::IsomorphicHelpers.log "Warning: request for server side data during scope evaluation: #{e.message}", :warning
495
391
  return_val
496
392
  ensure
497
393
  @catch_db_requests = false
@@ -509,13 +405,12 @@ module ReactiveRecord
509
405
  @destroyed = false
510
406
  model.reflect_on_all_associations.each do |association|
511
407
  if association.collection?
512
- attributes[association.attribute].replace([]) if attributes[association.attribute]
408
+ @attributes[association.attribute].replace([]) if @attributes[association.attribute]
513
409
  else
514
410
  @ar_instance.send("#{association.attribute}=", nil)
515
411
  end
516
412
  end
517
413
  @destroyed = true
518
414
  end
519
-
520
415
  end
521
416
  end