reactive-record 0.7.5 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/reactive_record/active_record/associations.rb +6 -1
- data/lib/reactive_record/active_record/class_methods.rb +11 -2
- data/lib/reactive_record/active_record/reactive_record/base.rb +5 -1
- data/lib/reactive_record/active_record/reactive_record/collection.rb +0 -4
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +5 -0
- data/lib/reactive_record/server_data_cache.rb +36 -21
- data/lib/reactive_record/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8548152ff489f1a0eb74a6eb0acbe08bcf94acb0
|
4
|
+
data.tar.gz: 2f6578db7396a607c8b3e61bea163fb55c5699c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: daab93265cb69a09597a46ed12cafda5975abdba0ac6eddb82b74123448ced47ee3d39b889d9ad7fc28ddf85bc7999ff73db8fd69b7fe76b9ce540571b51132a
|
7
|
+
data.tar.gz: e5ea4f5e44394b9103636a3b0081b7671caea1b90ab8627a5ba9b66976bcaaab212819da3e56aa3739a7903ef5cc1b98ddfb5fbbb7c1904ab6d9693241bef628
|
@@ -24,13 +24,18 @@ module ActiveRecord
|
|
24
24
|
owner_class.reflect_on_all_associations << self
|
25
25
|
@owner_class = owner_class
|
26
26
|
@macro = macro
|
27
|
+
@options = options
|
27
28
|
@klass_name = options[:class_name] || (collection? && name.camelize.gsub(/s$/,"")) || name.camelize
|
29
|
+
if @klass_name < ActiveRecord::Base
|
30
|
+
@klass = @klass_name
|
31
|
+
@klass_name = @klass_name.name
|
32
|
+
end rescue nil
|
28
33
|
@association_foreign_key = options[:foreign_key] || (macro == :belongs_to && "#{name}_id") || "#{@owner_class.name.underscore}_id"
|
29
34
|
@attribute = name
|
30
35
|
end
|
31
36
|
|
32
37
|
def inverse_of
|
33
|
-
unless @inverse_of
|
38
|
+
unless @options[:through] or @inverse_of
|
34
39
|
inverse_association = klass.reflect_on_all_associations.detect { | association | association.association_foreign_key == @association_foreign_key }
|
35
40
|
raise "Association #{@owner_class}.#{attribute} (foreign_key: #{@association_foreign_key}) has no inverse in #{@klass_name}" unless inverse_association
|
36
41
|
@inverse_of = inverse_association.attribute
|
@@ -62,11 +62,20 @@ module ActiveRecord
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def scope(name, body)
|
65
|
-
singleton_class.send(:define_method, name)
|
65
|
+
singleton_class.send(:define_method, name) do
|
66
|
+
ReactiveRecord::Base.class_scopes(self)[name] ||= ReactiveRecord::Collection.new(self, nil, nil, self, name)
|
67
|
+
end
|
68
|
+
singleton_class.send(:define_method, "#{name}=") do |collection|
|
69
|
+
ReactiveRecord::Base.class_scopes(self)[name] = collection
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
def all
|
69
|
-
ReactiveRecord::Collection.new(self, nil, nil, self, "all")
|
74
|
+
ReactiveRecord::Base.class_scopes(self)[:all] ||= ReactiveRecord::Collection.new(self, nil, nil, self, "all")
|
75
|
+
end
|
76
|
+
|
77
|
+
def all=(collection)
|
78
|
+
ReactiveRecord::Base.class_scopes(self)[:all] = collection
|
70
79
|
end
|
71
80
|
|
72
81
|
[:belongs_to, :has_many, :has_one].each do |macro|
|
@@ -48,6 +48,10 @@ module ReactiveRecord
|
|
48
48
|
ServerDataCache.load_from_json(json, target)
|
49
49
|
@data_loading = false
|
50
50
|
end
|
51
|
+
|
52
|
+
def self.class_scopes(model)
|
53
|
+
@class_scopes[model.base_class]
|
54
|
+
end
|
51
55
|
|
52
56
|
def self.find(model, attribute, value)
|
53
57
|
# will return the unique record with this attribute-value pair
|
@@ -165,7 +169,7 @@ module ReactiveRecord
|
|
165
169
|
attributes[attribute].attributes[inverse_of] = nil if attributes[attribute]
|
166
170
|
value.attributes[inverse_of] = @ar_instance
|
167
171
|
React::State.set_state(value.instance_variable_get(:@backing_record), inverse_of, @ar_instance) unless data_loading?
|
168
|
-
|
172
|
+
elsif attributes[attribute]
|
169
173
|
attributes[attribute].attributes[inverse_of] = nil
|
170
174
|
end
|
171
175
|
end
|
@@ -3,10 +3,6 @@ module ReactiveRecord
|
|
3
3
|
class Collection
|
4
4
|
|
5
5
|
def initialize(target_klass, owner = nil, association = nil, *vector)
|
6
|
-
if association and (association.macro != :has_many or association.klass != target_klass)
|
7
|
-
message = "unimplemented association #{owner} :#{association.macro} #{association.attribute}"
|
8
|
-
`console.error(#{message})`
|
9
|
-
end
|
10
6
|
@owner = owner # can be nil if this is an outer most scope
|
11
7
|
@association = association
|
12
8
|
@target_klass = target_klass
|
@@ -11,6 +11,7 @@ module ReactiveRecord
|
|
11
11
|
@server_data_cache = ReactiveRecord::ServerDataCache.new
|
12
12
|
else
|
13
13
|
@records = Hash.new { |hash, key| hash[key] = [] }
|
14
|
+
@class_scopes = Hash.new { |hash, key| hash[key] = {} }
|
14
15
|
if on_opal_client?
|
15
16
|
@pending_fetches = []
|
16
17
|
@last_fetch_at = Time.now
|
@@ -152,12 +153,16 @@ module ReactiveRecord
|
|
152
153
|
last_fetch_at = @last_fetch_at
|
153
154
|
pending_fetches = @pending_fetches.uniq
|
154
155
|
log(["Server Fetching: %o", pending_fetches.to_n])
|
156
|
+
start_time = Time.now
|
155
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")
|
156
160
|
begin
|
157
161
|
ReactiveRecord::Base.load_from_json(response.json)
|
158
162
|
rescue Exception => e
|
159
163
|
log("Exception raised while loading json from server: #{e}", :error)
|
160
164
|
end
|
165
|
+
log(" Processed in: #{(Time.now-fetch_time).to_i}s")
|
161
166
|
log([" Returned: %o", response.json.to_n])
|
162
167
|
ReactiveRecord.run_blocks_to_load
|
163
168
|
ReactiveRecord::WhileLoading.loaded_at last_fetch_at
|
@@ -95,9 +95,10 @@ module ReactiveRecord
|
|
95
95
|
if RUBY_ENGINE != 'opal'
|
96
96
|
|
97
97
|
def [](*vector)
|
98
|
-
|
98
|
+
root = CacheItem.new(@cache, vector[0])
|
99
|
+
vector[1..-1].inject(root) { |cache_item, method| cache_item.apply_method method if cache_item }
|
99
100
|
vector[0] = vector[0].constantize
|
100
|
-
new_items = @cache.select { | cache_item | cache_item.
|
101
|
+
new_items = @cache.select { | cache_item | cache_item.root == root}
|
101
102
|
@requested_cache_items += new_items
|
102
103
|
new_items.last.value if new_items.last
|
103
104
|
end
|
@@ -128,6 +129,7 @@ module ReactiveRecord
|
|
128
129
|
|
129
130
|
attr_reader :vector
|
130
131
|
attr_reader :record_chain
|
132
|
+
attr_reader :root
|
131
133
|
|
132
134
|
def value
|
133
135
|
@ar_object
|
@@ -138,7 +140,10 @@ module ReactiveRecord
|
|
138
140
|
end
|
139
141
|
|
140
142
|
def self.new(db_cache, klass)
|
141
|
-
|
143
|
+
klass_constant = klass.constantize
|
144
|
+
if existing = db_cache.detect { |cached_item| cached_item.vector == [klass_constant] }
|
145
|
+
return existing
|
146
|
+
end
|
142
147
|
super
|
143
148
|
end
|
144
149
|
|
@@ -149,18 +154,25 @@ module ReactiveRecord
|
|
149
154
|
@ar_object = klass
|
150
155
|
@record_chain = []
|
151
156
|
@parent = nil
|
157
|
+
@root = self
|
152
158
|
db_cache << self
|
153
159
|
end
|
154
160
|
|
155
161
|
def apply_method_to_cache(method, &block)
|
156
162
|
@db_cache.inject(nil) do | representative, cache_item |
|
157
163
|
if cache_item.vector == vector
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
+
begin
|
165
|
+
new_ar_object = yield cache_item
|
166
|
+
cache_item.clone.instance_eval do
|
167
|
+
@vector = @vector + [method] # don't push it on since you need a new vector!
|
168
|
+
@ar_object = new_ar_object
|
169
|
+
@db_cache << self
|
170
|
+
@parent = cache_item
|
171
|
+
@root = cache_item.root
|
172
|
+
self
|
173
|
+
end
|
174
|
+
rescue
|
175
|
+
representative
|
164
176
|
end
|
165
177
|
else
|
166
178
|
representative
|
@@ -185,10 +197,13 @@ module ReactiveRecord
|
|
185
197
|
else
|
186
198
|
apply_method_to_cache(method) {[]}
|
187
199
|
end
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
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
|
192
207
|
end
|
193
208
|
end
|
194
209
|
|
@@ -196,7 +211,7 @@ module ReactiveRecord
|
|
196
211
|
if @parent
|
197
212
|
if method == "*"
|
198
213
|
@parent.as_hash({@ar_object.id => children})
|
199
|
-
elsif @ar_object.class < ActiveRecord::Base
|
214
|
+
elsif @ar_object.class < ActiveRecord::Base and children.is_a? Hash
|
200
215
|
@parent.as_hash({method => children.merge({
|
201
216
|
:id => [@ar_object.id],
|
202
217
|
@ar_object.class.inheritance_column => [@ar_object[@ar_object.class.inheritance_column]],
|
@@ -216,31 +231,31 @@ module ReactiveRecord
|
|
216
231
|
end
|
217
232
|
|
218
233
|
def self.load_from_json(tree, target = nil)
|
219
|
-
|
234
|
+
ignore_all = nil
|
220
235
|
tree.each do |method, value|
|
221
236
|
method = JSON.parse(method) rescue method
|
222
237
|
new_target = nil
|
223
238
|
if !target
|
224
239
|
load_from_json(value, Object.const_get(method))
|
225
240
|
elsif method == "*all"
|
226
|
-
target.replace value.collect { |id| target.proxy_association.klass.find(id) }
|
241
|
+
target.replace value.collect { |id| target.proxy_association.klass.find(id) } unless ignore_all
|
227
242
|
elsif method.is_a? Integer or method =~ /^[0-9]+$/
|
228
|
-
|
229
|
-
target << new_target
|
243
|
+
ignore_all = true
|
244
|
+
target << (new_target = target.proxy_association.klass.find(method))
|
230
245
|
elsif method.is_a? Array
|
231
|
-
new_target = target.send *method
|
246
|
+
new_target = target.send *method unless value.is_a? Array # value is an array if scope returns nil
|
232
247
|
elsif value.is_a? Array
|
233
248
|
target.send "#{method}=", value.first
|
234
249
|
elsif value.is_a? Hash and value[:id] and value[:id].first
|
235
250
|
new_target = target.class.reflect_on_association(method).klass.find(value[:id].first)
|
236
251
|
target.send "#{method}=", new_target
|
237
252
|
else
|
238
|
-
new_target = target.send
|
239
|
-
(new_target = target.send "#{method}=", new_target) rescue nil # this can happen for example if you say TodoItems.all
|
253
|
+
new_target = target.send("#{method}=", target.send(method))
|
240
254
|
end
|
241
255
|
load_from_json(value, new_target) if new_target
|
242
256
|
end
|
243
257
|
target.save if target.respond_to? :save
|
258
|
+
|
244
259
|
end
|
245
260
|
|
246
261
|
|
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.6
|
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-
|
11
|
+
date: 2015-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|