reactive-record 0.7.6 → 0.7.7
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.
- checksums.yaml +4 -4
- data/app/controllers/reactive_record/reactive_record_controller.rb +4 -4
- data/lib/reactive-record.rb +1 -0
- data/lib/reactive_record/active_record/associations.rb +3 -1
- data/lib/reactive_record/active_record/class_methods.rb +3 -1
- data/lib/reactive_record/active_record/instance_methods.rb +5 -2
- data/lib/reactive_record/active_record/reactive_record/base.rb +10 -6
- data/lib/reactive_record/active_record/reactive_record/collection.rb +10 -2
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +86 -50
- data/lib/reactive_record/active_record/reactive_record/while_loading.rb +3 -3
- data/lib/reactive_record/permissions.rb +94 -0
- data/lib/reactive_record/server_data_cache.rb +15 -14
- data/lib/reactive_record/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e925fd65899df1cb77f96d9f3ccd69ec217c84b0
|
4
|
+
data.tar.gz: 758b5f711b45aa013975580fb6e35efe0e84d1b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0488d3001210b59a6e041807c4766b9110986b9f66e6327eb06214252d874d5b8c6873e96897c92c8f7c7c0a24a1dacc56f64d947a09f883eaae4a338e2d1494
|
7
|
+
data.tar.gz: 6a37ddf21f528087ee68fea326eead883c740b7b61697106593a2089a58783173b9d8e0ecdfd263cce86d4987a9b6f7a76800afe9fa35857244b249a062c1d20
|
@@ -2,19 +2,19 @@ require 'reactive_record/server_data_cache'
|
|
2
2
|
|
3
3
|
module ReactiveRecord
|
4
4
|
|
5
|
-
class ReactiveRecordController < ApplicationController
|
5
|
+
class ReactiveRecordController < ::ApplicationController
|
6
6
|
|
7
7
|
def fetch
|
8
|
-
render :json => ReactiveRecord::ServerDataCache[params[:pending_fetches]]
|
8
|
+
render :json => ReactiveRecord::ServerDataCache[params[:pending_fetches], acting_user]
|
9
9
|
end
|
10
10
|
|
11
11
|
|
12
12
|
def save
|
13
|
-
render :json => ReactiveRecord::Base.save_records(params[:models], params[:associations])
|
13
|
+
render :json => ReactiveRecord::Base.save_records(params[:models], params[:associations], acting_user)
|
14
14
|
end
|
15
15
|
|
16
16
|
def destroy
|
17
|
-
render :json => ReactiveRecord::Base.destroy_record(params[:model], params[:id], params[:vector])
|
17
|
+
render :json => ReactiveRecord::Base.destroy_record(params[:model], params[:id], params[:vector], acting_user)
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
data/lib/reactive-record.rb
CHANGED
@@ -36,7 +36,9 @@ module ActiveRecord
|
|
36
36
|
|
37
37
|
def inverse_of
|
38
38
|
unless @options[:through] or @inverse_of
|
39
|
-
inverse_association = klass.reflect_on_all_associations.detect
|
39
|
+
inverse_association = klass.reflect_on_all_associations.detect do | association |
|
40
|
+
association.association_foreign_key == @association_foreign_key and association.klass.base_class == @owner_class.base_class
|
41
|
+
end
|
40
42
|
raise "Association #{@owner_class}.#{attribute} (foreign_key: #{@association_foreign_key}) has no inverse in #{@klass_name}" unless inverse_association
|
41
43
|
@inverse_of = inverse_association.attribute
|
42
44
|
end
|
@@ -79,7 +79,9 @@ module ActiveRecord
|
|
79
79
|
end
|
80
80
|
|
81
81
|
[:belongs_to, :has_many, :has_one].each do |macro|
|
82
|
-
define_method(macro) do |name, opts
|
82
|
+
define_method(macro) do |*args| # is this a bug in opal? saying name, scope=nil, opts={} does not work!
|
83
|
+
name = args.first
|
84
|
+
opts = args.last
|
83
85
|
Associations::AssociationReflection.new(base_class, macro, name, opts)
|
84
86
|
end
|
85
87
|
end
|
@@ -11,8 +11,11 @@ module ActiveRecord
|
|
11
11
|
@backing_record = hash
|
12
12
|
else
|
13
13
|
# standard active_record new -> creates a new instance, primary key is ignored if present
|
14
|
-
|
15
|
-
@backing_record = ReactiveRecord::Base.new(self.class,
|
14
|
+
# we have to build the backing record first then initialize it so associations work correctly
|
15
|
+
@backing_record = ReactiveRecord::Base.new(self.class, {}, self)
|
16
|
+
@backing_record.instance_eval do
|
17
|
+
self.class.load_data { hash.each { |attribute, value| reactive_set!(attribute, value) unless attribute == primary_key } }
|
18
|
+
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
@@ -43,10 +43,14 @@ module ReactiveRecord
|
|
43
43
|
self.class.data_loading?
|
44
44
|
end
|
45
45
|
|
46
|
+
def self.load_data(&block)
|
47
|
+
current_data_loading, @data_loading = [@data_loading, true]
|
48
|
+
yield
|
49
|
+
@data_loading = current_data_loading
|
50
|
+
end
|
51
|
+
|
46
52
|
def self.load_from_json(json, target = nil)
|
47
|
-
|
48
|
-
ServerDataCache.load_from_json(json, target)
|
49
|
-
@data_loading = false
|
53
|
+
load_data { ServerDataCache.load_from_json(json, target) }
|
50
54
|
end
|
51
55
|
|
52
56
|
def self.class_scopes(model)
|
@@ -100,9 +104,9 @@ module ReactiveRecord
|
|
100
104
|
|
101
105
|
def initialize(model, hash = {}, ar_instance = nil)
|
102
106
|
@model = model
|
103
|
-
@synced_attributes = {}
|
104
|
-
@attributes = hash
|
105
107
|
@ar_instance = ar_instance
|
108
|
+
@synced_attributes = {}
|
109
|
+
@attributes = {}
|
106
110
|
records[model] << self
|
107
111
|
end
|
108
112
|
|
@@ -203,7 +207,7 @@ module ReactiveRecord
|
|
203
207
|
def sync!(hash = {})
|
204
208
|
@attributes.merge! hash
|
205
209
|
@synced_attributes = @attributes.dup
|
206
|
-
@synced_attributes.each { |key, value| @synced_attributes[key] = value.
|
210
|
+
@synced_attributes.each { |key, value| @synced_attributes[key] = value.dup_for_sync if value.is_a? Collection }
|
207
211
|
@saving = false
|
208
212
|
React::State.set_state(self, self, :synced) unless data_loading?
|
209
213
|
self
|
@@ -13,6 +13,14 @@ module ReactiveRecord
|
|
13
13
|
end
|
14
14
|
@scopes = {}
|
15
15
|
end
|
16
|
+
|
17
|
+
def dup_for_sync
|
18
|
+
self.dup.instance_eval do
|
19
|
+
@collection = @collection.dup if @collection
|
20
|
+
@scopes = @scopes.dup
|
21
|
+
self
|
22
|
+
end
|
23
|
+
end
|
16
24
|
|
17
25
|
def all
|
18
26
|
@dummy_collection.notify if @dummy_collection
|
@@ -55,10 +63,10 @@ module ReactiveRecord
|
|
55
63
|
|
56
64
|
|
57
65
|
def <<(item)
|
58
|
-
|
66
|
+
backing_record = item.instance_variable_get(:@backing_record)
|
67
|
+
if backing_record and @owner and @association and inverse_of = @association.inverse_of
|
59
68
|
item.attributes[inverse_of].attributes[@association.attribute].delete(item) if item.attributes[inverse_of] and item.attributes[inverse_of].attributes[@association.attribute]
|
60
69
|
item.attributes[inverse_of] = @owner
|
61
|
-
backing_record = item.instance_variable_get(:@backing_record)
|
62
70
|
React::State.set_state(backing_record, inverse_of, @owner) unless backing_record.data_loading?
|
63
71
|
end
|
64
72
|
all << item unless all.include? item
|
@@ -6,10 +6,11 @@ module ReactiveRecord
|
|
6
6
|
|
7
7
|
include React::IsomorphicHelpers
|
8
8
|
|
9
|
-
before_first_mount do
|
9
|
+
before_first_mount do |context|
|
10
10
|
if RUBY_ENGINE != 'opal'
|
11
|
-
@server_data_cache = ReactiveRecord::ServerDataCache.new
|
11
|
+
@server_data_cache = ReactiveRecord::ServerDataCache.new(context.controller.acting_user)
|
12
12
|
else
|
13
|
+
@fetch_scheduled = nil
|
13
14
|
@records = Hash.new { |hash, key| hash[key] = [] }
|
14
15
|
@class_scopes = Hash.new { |hash, key| hash[key] = {} }
|
15
16
|
if on_opal_client?
|
@@ -150,26 +151,31 @@ module ReactiveRecord
|
|
150
151
|
|
151
152
|
def self.schedule_fetch
|
152
153
|
@fetch_scheduled ||= after(0.001) do
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
154
|
+
if @pending_fetches.count > 0 # during testing we might reset the context while there are pending fetches
|
155
|
+
last_fetch_at = @last_fetch_at
|
156
|
+
pending_fetches = @pending_fetches.uniq
|
157
|
+
log(["Server Fetching: %o", pending_fetches.to_n])
|
158
|
+
start_time = Time.now
|
159
|
+
HTTP.post(`window.ReactiveRecordEnginePath`, payload: {pending_fetches: pending_fetches}).then do |response|
|
160
|
+
fetch_time = Time.now
|
161
|
+
log(" Fetched in: #{(fetch_time-start_time).to_i}s")
|
162
|
+
begin
|
163
|
+
ReactiveRecord::Base.load_from_json(response.json)
|
164
|
+
rescue Exception => e
|
165
|
+
log("Exception raised while loading json from server: #{e}", :error)
|
166
|
+
end
|
167
|
+
log(" Processed in: #{(Time.now-fetch_time).to_i}s")
|
168
|
+
log([" Returned: %o", response.json.to_n])
|
169
|
+
ReactiveRecord.run_blocks_to_load
|
170
|
+
ReactiveRecord::WhileLoading.loaded_at last_fetch_at
|
171
|
+
end.fail do |response|
|
172
|
+
log("Fetch failed", :error)
|
173
|
+
ReactiveRecord.run_blocks_to_load(response.body)
|
164
174
|
end
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
end if @pending_fetches.count > 0
|
170
|
-
@pending_fetches = []
|
171
|
-
@last_fetch_at = Time.now
|
172
|
-
@fetch_scheduled = nil
|
175
|
+
@pending_fetches = []
|
176
|
+
@last_fetch_at = Time.now
|
177
|
+
@fetch_scheduled = nil
|
178
|
+
end
|
173
179
|
end
|
174
180
|
end
|
175
181
|
|
@@ -182,7 +188,7 @@ module ReactiveRecord
|
|
182
188
|
if RUBY_ENGINE == 'opal'
|
183
189
|
|
184
190
|
def save(&block)
|
185
|
-
|
191
|
+
|
186
192
|
if data_loading?
|
187
193
|
|
188
194
|
sync!
|
@@ -241,18 +247,29 @@ module ReactiveRecord
|
|
241
247
|
internal_id, klass, attributes = item
|
242
248
|
backing_records[internal_id].sync!(attributes)
|
243
249
|
end
|
244
|
-
|
245
|
-
|
250
|
+
log("Reactive Record Save Failed: #{response.json[:message]}", :error) unless response.json[:success]
|
251
|
+
response.json[:saved_models].each do |model|
|
252
|
+
log(" Model: #{model[1]} Attributes: #{model[2]} Errors: #{model[3]}", :error) if model[3]
|
253
|
+
end
|
254
|
+
yield response.json[:success], response.json[:message], response.json[:saved_models] if block
|
255
|
+
promise.resolve response.json
|
246
256
|
end
|
247
257
|
promise
|
258
|
+
else
|
259
|
+
promise = Promise.new
|
260
|
+
yield true, nil if block
|
261
|
+
promise.resolve({success: true})
|
262
|
+
promise
|
248
263
|
end
|
249
264
|
end
|
250
265
|
|
251
266
|
else
|
252
267
|
|
253
|
-
def self.save_records(models, associations)
|
268
|
+
def self.save_records(models, associations, acting_user)
|
254
269
|
|
255
270
|
reactive_records = {}
|
271
|
+
new_models = []
|
272
|
+
saved_models = []
|
256
273
|
|
257
274
|
models.each do |model_to_save|
|
258
275
|
attributes = model_to_save[:attributes]
|
@@ -262,43 +279,61 @@ module ReactiveRecord
|
|
262
279
|
record = model.find(id)
|
263
280
|
keys = record.attributes.keys
|
264
281
|
attributes.each do |key, value|
|
265
|
-
|
282
|
+
if keys.include? key
|
283
|
+
record[key] = value
|
284
|
+
else
|
285
|
+
record.send("#{key}=",value)
|
286
|
+
end
|
266
287
|
end
|
267
288
|
record
|
268
289
|
else
|
269
290
|
record = model.new
|
270
291
|
keys = record.attributes.keys
|
271
292
|
attributes.each do |key, value|
|
272
|
-
|
293
|
+
if keys.include? key
|
294
|
+
record[key] = value
|
295
|
+
else
|
296
|
+
record.send("#{key}=",value)
|
297
|
+
end
|
273
298
|
end
|
299
|
+
new_models << record
|
274
300
|
record
|
275
301
|
end
|
276
302
|
end
|
277
303
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
304
|
+
ActiveRecord::Base.transaction do
|
305
|
+
|
306
|
+
associations.each do |association|
|
307
|
+
parent = reactive_records[association[:parent_id]]
|
308
|
+
parent.instance_variable_set("@reactive_record_#{association[:attribute]}_changed", true)
|
309
|
+
if parent.class.reflect_on_aggregation(association[:attribute].to_sym)
|
310
|
+
parent.send("#{association[:attribute]}=", reactive_records[association[:child_id]])
|
311
|
+
elsif parent.class.reflect_on_association(association[:attribute].to_sym).collection?
|
312
|
+
parent.send("#{association[:attribute]}") << reactive_records[association[:child_id]]
|
284
313
|
else
|
285
|
-
|
314
|
+
parent.send("#{association[:attribute]}=", reactive_records[association[:child_id]])
|
286
315
|
end
|
287
|
-
end
|
288
|
-
|
316
|
+
end if associations
|
317
|
+
|
318
|
+
has_errors = false
|
289
319
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
320
|
+
saved_models = reactive_records.collect do |reactive_record_id, model|
|
321
|
+
unless model.frozen?
|
322
|
+
saved = model.check_permission_with_acting_user(acting_user, new_models.include?(model) ? :create_permitted? : :update_permitted?).save
|
323
|
+
has_errors ||= !saved
|
324
|
+
[reactive_record_id, model.class.name, model.attributes, (saved ? nil : model.errors.full_messages)]
|
325
|
+
end
|
326
|
+
end.compact
|
327
|
+
|
328
|
+
raise "Could not save all models" if has_errors
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
{success: true, saved_models: saved_models }
|
298
333
|
|
299
334
|
rescue Exception => e
|
300
335
|
|
301
|
-
{success: false, saved_models: saved_models
|
336
|
+
{success: false, saved_models: saved_models, message: e.message}
|
302
337
|
|
303
338
|
end
|
304
339
|
|
@@ -325,11 +360,11 @@ module ReactiveRecord
|
|
325
360
|
if id or vector
|
326
361
|
HTTP.post(`window.ReactiveRecordEnginePath`+"/destroy", payload: {model: ar_instance.model_name, id: id, vector: vector}).then do |response|
|
327
362
|
yield response.json[:success], response.json[:message] if block
|
328
|
-
promise.resolve response.json
|
363
|
+
promise.resolve response.json
|
329
364
|
end
|
330
365
|
else
|
331
366
|
yield true, nil if block
|
332
|
-
promise.resolve true
|
367
|
+
promise.resolve({success: true})
|
333
368
|
end
|
334
369
|
|
335
370
|
@attributes = {}
|
@@ -341,15 +376,16 @@ module ReactiveRecord
|
|
341
376
|
|
342
377
|
else
|
343
378
|
|
344
|
-
def self.destroy_record(model, id, vector)
|
379
|
+
def self.destroy_record(model, id, vector, acting_user)
|
345
380
|
model = Object.const_get(model)
|
346
381
|
record = if id
|
347
382
|
model.find(id)
|
348
383
|
else
|
349
|
-
ServerDataCache.new[*vector]
|
384
|
+
ServerDataCache.new(acting_user)[*vector]
|
350
385
|
end
|
351
|
-
record.destroy
|
386
|
+
record.check_permission_with_acting_user(acting_user, :destroy_permitted?).destroy
|
352
387
|
{success: true, attributes: {}}
|
388
|
+
|
353
389
|
rescue Exception => e
|
354
390
|
{success: false, record: record, message: e.message}
|
355
391
|
end
|
@@ -23,14 +23,14 @@ module ReactiveRecord
|
|
23
23
|
@loads_pending = true
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.run_blocks_to_load
|
26
|
+
def self.run_blocks_to_load(failure = nil)
|
27
27
|
if @blocks_to_load
|
28
28
|
blocks_to_load = @blocks_to_load
|
29
29
|
@blocks_to_load = []
|
30
30
|
blocks_to_load.each do |promise_and_block|
|
31
31
|
@loads_pending = nil
|
32
|
-
result = promise_and_block.last.call
|
33
|
-
if @loads_pending
|
32
|
+
result = promise_and_block.last.call(failure)
|
33
|
+
if @loads_pending and !failure
|
34
34
|
@blocks_to_load << promise_and_block
|
35
35
|
else
|
36
36
|
promise_and_block.first.resolve result
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
|
3
|
+
attr_accessor :acting_user
|
4
|
+
|
5
|
+
def create_permitted?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
def update_permitted?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy_permitted?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def view_permitted?(attribute)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def only_changed?(*attributes)
|
22
|
+
(self.attributes.keys + self.class.reactive_record_association_keys).each do |key|
|
23
|
+
return false if self.send("#{key}_changed?") and !attributes.include? key
|
24
|
+
end
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def none_changed?(*attributes)
|
29
|
+
attributes.each do |key|
|
30
|
+
return false if self.send("#{key}_changed?")
|
31
|
+
end
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def any_changed?(*attributes)
|
36
|
+
attributes.each do |key|
|
37
|
+
return true if self.send("#{key}_changed?")
|
38
|
+
end
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def all_changed?(*attributes)
|
43
|
+
attributes.each do |key|
|
44
|
+
return false unless self.send("#{key}_changed?")
|
45
|
+
end
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
class << self
|
50
|
+
|
51
|
+
attr_reader :reactive_record_association_keys
|
52
|
+
|
53
|
+
[:has_many, :belongs_to, :composed_of].each do |macro|
|
54
|
+
define_method "#{macro}_with_reactive_record_add_changed_method".to_sym do |attr_name, *args, &block|
|
55
|
+
define_method "#{attr_name}_changed?".to_sym do
|
56
|
+
instance_variable_get "@reactive_record_#{attr_name}_changed".to_sym
|
57
|
+
end
|
58
|
+
(@reactive_record_association_keys ||= []) << attr_name
|
59
|
+
send "#{macro}_without_reactive_record_add_changed_method".to_sym, attr_name, *args, &block
|
60
|
+
end
|
61
|
+
alias_method_chain macro, :reactive_record_add_changed_method
|
62
|
+
end
|
63
|
+
|
64
|
+
def belongs_to_with_reactive_record_add_is_method(attr_name, scope = nil, options = {})
|
65
|
+
define_method "#{attr_name}_is?".to_sym do |model|
|
66
|
+
send(options[:foreign_key] || "#{attr_name}_id") == model.id
|
67
|
+
end
|
68
|
+
belongs_to_without_reactive_record_add_is_method(attr_name, scope, options)
|
69
|
+
end
|
70
|
+
|
71
|
+
alias_method_chain :belongs_to, :reactive_record_add_is_method
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def check_permission_with_acting_user(user, permission, *args)
|
77
|
+
old = acting_user
|
78
|
+
self.acting_user = user
|
79
|
+
if self.send(permission, *args)
|
80
|
+
self.acting_user = old
|
81
|
+
self
|
82
|
+
else
|
83
|
+
raise "ReactiveRecord Access Violation: #{permission}(#{args}) returned false"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
class ActionController::Base
|
90
|
+
|
91
|
+
def acting_user
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -86,8 +86,9 @@ module ReactiveRecord
|
|
86
86
|
|
87
87
|
|
88
88
|
class ServerDataCache
|
89
|
-
|
90
|
-
def initialize
|
89
|
+
|
90
|
+
def initialize(acting_user)
|
91
|
+
@acting_user = acting_user
|
91
92
|
@cache = []
|
92
93
|
@requested_cache_items = []
|
93
94
|
end
|
@@ -95,7 +96,7 @@ module ReactiveRecord
|
|
95
96
|
if RUBY_ENGINE != 'opal'
|
96
97
|
|
97
98
|
def [](*vector)
|
98
|
-
root = CacheItem.new(@cache, vector[0])
|
99
|
+
root = CacheItem.new(@cache, @acting_user, vector[0])
|
99
100
|
vector[1..-1].inject(root) { |cache_item, method| cache_item.apply_method method if cache_item }
|
100
101
|
vector[0] = vector[0].constantize
|
101
102
|
new_items = @cache.select { | cache_item | cache_item.root == root}
|
@@ -103,8 +104,8 @@ module ReactiveRecord
|
|
103
104
|
new_items.last.value if new_items.last
|
104
105
|
end
|
105
106
|
|
106
|
-
def self.[](vectors)
|
107
|
-
cache = new
|
107
|
+
def self.[](vectors, acting_user)
|
108
|
+
cache = new(acting_user)
|
108
109
|
vectors.each { |vector| cache[*vector] }
|
109
110
|
cache.as_json
|
110
111
|
end
|
@@ -130,6 +131,7 @@ module ReactiveRecord
|
|
130
131
|
attr_reader :vector
|
131
132
|
attr_reader :record_chain
|
132
133
|
attr_reader :root
|
134
|
+
attr_reader :acting_user
|
133
135
|
|
134
136
|
def value
|
135
137
|
@ar_object
|
@@ -139,7 +141,7 @@ module ReactiveRecord
|
|
139
141
|
vector.last
|
140
142
|
end
|
141
143
|
|
142
|
-
def self.new(db_cache, klass)
|
144
|
+
def self.new(db_cache, acting_user, klass)
|
143
145
|
klass_constant = klass.constantize
|
144
146
|
if existing = db_cache.detect { |cached_item| cached_item.vector == [klass_constant] }
|
145
147
|
return existing
|
@@ -147,9 +149,10 @@ module ReactiveRecord
|
|
147
149
|
super
|
148
150
|
end
|
149
151
|
|
150
|
-
def initialize(db_cache, klass)
|
152
|
+
def initialize(db_cache, acting_user, klass)
|
151
153
|
klass = klass.constantize
|
152
154
|
@db_cache = db_cache
|
155
|
+
@acting_user = acting_user
|
153
156
|
@vector = [klass]
|
154
157
|
@ar_object = klass
|
155
158
|
@record_chain = []
|
@@ -161,6 +164,9 @@ module ReactiveRecord
|
|
161
164
|
def apply_method_to_cache(method, &block)
|
162
165
|
@db_cache.inject(nil) do | representative, cache_item |
|
163
166
|
if cache_item.vector == vector
|
167
|
+
if @ar_object.class < ActiveRecord::Base and @ar_object.attributes.has_key?(method)
|
168
|
+
@ar_object.check_permission_with_acting_user(acting_user, :view_permitted?, method)
|
169
|
+
end
|
164
170
|
begin
|
165
171
|
new_ar_object = yield cache_item
|
166
172
|
cache_item.clone.instance_eval do
|
@@ -197,13 +203,8 @@ module ReactiveRecord
|
|
197
203
|
else
|
198
204
|
apply_method_to_cache(method) {[]}
|
199
205
|
end
|
200
|
-
else
|
201
|
-
|
202
|
-
r = apply_method_to_cache(method) { |cache_item| cache_item.value.send(*method) }# rescue nil } # rescue in case we are on a nil association
|
203
|
-
puts "representative method = #{r}"
|
204
|
-
r
|
205
|
-
#else
|
206
|
-
# self
|
206
|
+
else
|
207
|
+
apply_method_to_cache(method) { |cache_item| cache_item.value.send(*method) }
|
207
208
|
end
|
208
209
|
end
|
209
210
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactive-record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitch VanDuyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -162,6 +162,7 @@ files:
|
|
162
162
|
- lib/reactive_record/active_record/reactive_record/while_loading.rb
|
163
163
|
- lib/reactive_record/engine.rb
|
164
164
|
- lib/reactive_record/interval.rb
|
165
|
+
- lib/reactive_record/permissions.rb
|
165
166
|
- lib/reactive_record/serializers.rb
|
166
167
|
- lib/reactive_record/server_data_cache.rb
|
167
168
|
- lib/reactive_record/version.rb
|