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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8548152ff489f1a0eb74a6eb0acbe08bcf94acb0
4
- data.tar.gz: 2f6578db7396a607c8b3e61bea163fb55c5699c9
3
+ metadata.gz: e925fd65899df1cb77f96d9f3ccd69ec217c84b0
4
+ data.tar.gz: 758b5f711b45aa013975580fb6e35efe0e84d1b5
5
5
  SHA512:
6
- metadata.gz: daab93265cb69a09597a46ed12cafda5975abdba0ac6eddb82b74123448ced47ee3d39b889d9ad7fc28ddf85bc7999ff73db8fd69b7fe76b9ce540571b51132a
7
- data.tar.gz: e5ea4f5e44394b9103636a3b0081b7671caea1b90ab8627a5ba9b66976bcaaab212819da3e56aa3739a7903ef5cc1b98ddfb5fbbb7c1904ab6d9693241bef628
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
@@ -17,6 +17,7 @@ else
17
17
 
18
18
  require "opal"
19
19
  require "reactive_record/version"
20
+ require "reactive_record/permissions"
20
21
  require "reactive_record/engine"
21
22
  require "reactive_record/server_data_cache"
22
23
  require "reactive_record/active_record/reactive_record/isomorphic_base"
@@ -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 { | association | association.association_foreign_key == @association_foreign_key }
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
- hash[primary_key] = nil
15
- @backing_record = ReactiveRecord::Base.new(self.class, hash, self)
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
- @data_loading = true
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.dup if value.is_a? Collection }
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
- if @owner and @association and inverse_of = @association.inverse_of
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
- last_fetch_at = @last_fetch_at
154
- pending_fetches = @pending_fetches.uniq
155
- log(["Server Fetching: %o", pending_fetches.to_n])
156
- start_time = Time.now
157
- HTTP.post(`window.ReactiveRecordEnginePath`, payload: {pending_fetches: pending_fetches}).then do |response|
158
- fetch_time = Time.now
159
- log(" Fetched in: #{(fetch_time-start_time).to_i}s")
160
- begin
161
- ReactiveRecord::Base.load_from_json(response.json)
162
- rescue Exception => e
163
- log("Exception raised while loading json from server: #{e}", :error)
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
- log(" Processed in: #{(Time.now-fetch_time).to_i}s")
166
- log([" Returned: %o", response.json.to_n])
167
- ReactiveRecord.run_blocks_to_load
168
- ReactiveRecord::WhileLoading.loaded_at last_fetch_at
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
- yield response.json[:success], response.json[:message] if block
245
- promise.resolve response.json[:success], response.json[:message]
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
- record[key] = value if keys.include? key
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
- record[key] = value if keys.include? key
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
- associations.each do |association|
279
- begin
280
- if reactive_records[association[:parent_id]].class.reflect_on_aggregation(association[:attribute].to_sym)
281
- reactive_records[association[:parent_id]].send("#{association[:attribute]}=", reactive_records[association[:child_id]])
282
- elsif reactive_records[association[:parent_id]].class.reflect_on_association(association[:attribute].to_sym).collection?
283
- reactive_records[association[:parent_id]].send("#{association[:attribute]}") << reactive_records[association[:child_id]]
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
- reactive_records[association[:parent_id]].send("#{association[:attribute]}=", reactive_records[association[:child_id]])
314
+ parent.send("#{association[:attribute]}=", reactive_records[association[:child_id]])
286
315
  end
287
- end
288
- end if associations
316
+ end if associations
317
+
318
+ has_errors = false
289
319
 
290
- saved_models = reactive_records.collect do |reactive_record_id, model|
291
- unless model.frozen?
292
- saved = model.save
293
- [reactive_record_id, model.class.name, model.attributes, saved]
294
- end
295
- end.compact
296
-
297
- {success: true, saved_models: saved_models || []}
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 || [], message: e.message}
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[:success], response.json[:message]
363
+ promise.resolve response.json
329
364
  end
330
365
  else
331
366
  yield true, nil if block
332
- promise.resolve true, nil
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 # @ar_object.respond_to? [*method].first
201
- puts "apply #{method} to #{@vector}"
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
 
@@ -1,3 +1,3 @@
1
1
  module ReactiveRecord
2
- VERSION = "0.7.6"
2
+ VERSION = "0.7.7"
3
3
  end
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.6
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-08-28 00:00:00.000000000 Z
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