hyper-mesh 1.0.0.lap27 → 1.0.0.lap28

Sign up to get free protection for your applications and to get access to all the features.
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