reactive-record 0.7.5 → 0.7.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cedb48995b7ce8ff657d9219b89de03a708cbe13
4
- data.tar.gz: 848a09867b41cf9dbaaca1660fe451179ce79928
3
+ metadata.gz: 8548152ff489f1a0eb74a6eb0acbe08bcf94acb0
4
+ data.tar.gz: 2f6578db7396a607c8b3e61bea163fb55c5699c9
5
5
  SHA512:
6
- metadata.gz: 0ac3263bac093e1e702d072bfe6fc1c1d8a8be9e3f162f2097f8df1832cf4938c71a94a1f30c539bb1da5795b4a23e480eb2391da5b56fe9199d195484575927
7
- data.tar.gz: 50831135ec14dc12423379e089b491e4868db815fab7cf65b7564e1155babaa7563aeebdba717248b7ea181b06cb290cfc01a758b171b9209c9b187b13307fc1
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) { ReactiveRecord::Collection.new(self, nil, nil, self, 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
- else
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
- vector.inject(CacheItem.new(@cache, vector[0])) { |cache_item, method| cache_item.apply_method method }
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.vector == vector}
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
- return existing if existing = db_cache.detect { |cached_item| cached_item.vector == [klass] }
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
- cache_item.clone.instance_eval do
159
- @vector = @vector + [method] # don't push it on since you need a new vector!
160
- @ar_object = yield cache_item
161
- @db_cache << self
162
- @parent = cache_item
163
- self
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
- elsif @ar_object.respond_to? [*method].first
189
- apply_method_to_cache(method) { |cache_item| cache_item.value.send(*method) rescue nil } # rescue in case we are on a nil association
190
- else
191
- self
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
- tree.delete("*all") if tree["*"]
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
- new_target = target.proxy_association.klass.find(method)
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 *method
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
 
@@ -1,3 +1,3 @@
1
1
  module ReactiveRecord
2
- VERSION = "0.7.5"
2
+ VERSION = "0.7.6"
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.5
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-21 00:00:00.000000000 Z
11
+ date: 2015-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails