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