hyper-model 1.0.alpha1.3 → 1.0.alpha1.8
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/.gitignore +4 -1
- data/.rspec +0 -1
- data/Gemfile +6 -5
- data/Rakefile +18 -6
- data/hyper-model.gemspec +12 -20
- data/lib/active_record_base.rb +95 -28
- data/lib/enumerable/pluck.rb +3 -2
- data/lib/hyper-model.rb +4 -1
- data/lib/hyper_model/version.rb +1 -1
- data/lib/hyper_react/input_tags.rb +2 -1
- data/lib/reactive_record/active_record/associations.rb +125 -35
- data/lib/reactive_record/active_record/base.rb +32 -0
- data/lib/reactive_record/active_record/class_methods.rb +125 -53
- data/lib/reactive_record/active_record/error.rb +2 -0
- data/lib/reactive_record/active_record/errors.rb +8 -4
- data/lib/reactive_record/active_record/instance_methods.rb +73 -5
- data/lib/reactive_record/active_record/public_columns_hash.rb +25 -26
- data/lib/reactive_record/active_record/reactive_record/backing_record_inspector.rb +22 -5
- data/lib/reactive_record/active_record/reactive_record/base.rb +50 -24
- data/lib/reactive_record/active_record/reactive_record/collection.rb +196 -63
- data/lib/reactive_record/active_record/reactive_record/dummy_polymorph.rb +22 -0
- data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +27 -15
- data/lib/reactive_record/active_record/reactive_record/getters.rb +33 -10
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +71 -44
- data/lib/reactive_record/active_record/reactive_record/lookup_tables.rb +5 -5
- data/lib/reactive_record/active_record/reactive_record/operations.rb +7 -1
- data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +3 -6
- data/lib/reactive_record/active_record/reactive_record/setters.rb +105 -68
- data/lib/reactive_record/active_record/reactive_record/while_loading.rb +22 -1
- data/lib/reactive_record/broadcast.rb +59 -25
- data/lib/reactive_record/interval.rb +3 -3
- data/lib/reactive_record/permissions.rb +1 -1
- data/lib/reactive_record/scope_description.rb +3 -2
- data/lib/reactive_record/server_data_cache.rb +78 -48
- data/polymorph-notes.md +143 -0
- metadata +52 -157
- data/Gemfile.lock +0 -440
@@ -168,12 +168,12 @@ end
|
|
168
168
|
module Kernel
|
169
169
|
# (see Browser::Window#after)
|
170
170
|
def after(time, &block)
|
171
|
-
|
171
|
+
$window.after(time, &block)
|
172
172
|
end
|
173
173
|
|
174
174
|
# (see Browser::Window#after!)
|
175
175
|
def after!(time, &block)
|
176
|
-
|
176
|
+
$window.after!(time, &block)
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
@@ -187,4 +187,4 @@ class Proc
|
|
187
187
|
def after!(time)
|
188
188
|
$window.after!(time, &self)
|
189
189
|
end
|
190
|
-
end
|
190
|
+
end
|
@@ -90,7 +90,7 @@ class ActiveRecord::Base
|
|
90
90
|
def belongs_to(attr_name, *args)
|
91
91
|
belongs_to_without_reactive_record_add_is_method(attr_name, *args).tap do
|
92
92
|
define_method "#{attr_name}_is?".to_sym do |model|
|
93
|
-
self.class.reflections[attr_name.to_s].foreign_key == model.id
|
93
|
+
attributes[self.class.reflections[attr_name.to_s].foreign_key] == model.id
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -93,8 +93,9 @@ module ReactiveRecord
|
|
93
93
|
vector = []
|
94
94
|
path.split('.').inject(@model) do |model, attribute|
|
95
95
|
association = model.reflect_on_association(attribute)
|
96
|
-
|
97
|
-
|
96
|
+
inverse_of = association.inverse_of if association
|
97
|
+
raise build_error(path, model, attribute) unless inverse_of
|
98
|
+
vector = [inverse_of, *vector]
|
98
99
|
@joins[association.klass] << vector
|
99
100
|
association.klass
|
100
101
|
end
|
@@ -260,45 +260,54 @@ module ReactiveRecord
|
|
260
260
|
def apply_method_to_cache(method)
|
261
261
|
@db_cache.cache.inject(nil) do |representative, cache_item|
|
262
262
|
if cache_item.vector == vector
|
263
|
-
|
264
|
-
#
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
263
|
+
begin
|
264
|
+
# error_recovery_method holds the current method that we are attempting to apply
|
265
|
+
# in case we throw an exception, and need to give the developer a meaningful message.
|
266
|
+
if method == "*"
|
267
|
+
# apply_star does the security check if value is present
|
268
|
+
cache_item.apply_star || representative
|
269
|
+
elsif method == "*all"
|
270
|
+
# if we secure the collection then we assume its okay to read the ids
|
271
|
+
error_recovery_method = [:all]
|
272
|
+
secured_value = cache_item.value.__secure_collection_check(cache_item)
|
273
|
+
cache_item.build_new_cache_item(timing(:active_record) { secured_value.collect { |record| record.id } }, method, method)
|
274
|
+
elsif method == "*count"
|
275
|
+
error_recovery_method = [:count]
|
276
|
+
secured_value = cache_item.value.__secure_collection_check(cache_item)
|
277
|
+
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.__secure_collection_check(cache_item).count }, method, method)
|
278
|
+
elsif preloaded_value = @preloaded_records[cache_item.absolute_vector + [method]]
|
279
|
+
# no security check needed since we already evaluated this
|
280
|
+
cache_item.build_new_cache_item(preloaded_value, method, method)
|
281
|
+
elsif aggregation = cache_item.aggregation?(method)
|
282
|
+
# aggregations are not protected
|
283
|
+
error_recovery_method = [method, :mapping, :all]
|
284
|
+
cache_item.build_new_cache_item(aggregation.mapping.collect { |attribute, accessor| cache_item.value[attribute] }, method, method)
|
283
285
|
else
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
286
|
+
if !cache_item.value || cache_item.value.is_a?(Array)
|
287
|
+
# seeing as we just returning representative, no check is needed (its already checked)
|
288
|
+
representative
|
289
|
+
elsif method == 'model_name'
|
290
|
+
error_recovery_method = [:model_name]
|
291
|
+
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.model_name }, method, method)
|
292
|
+
else
|
293
|
+
begin
|
294
|
+
secured_method = "__secure_remote_access_to_#{[*method].first}"
|
295
|
+
error_recovery_method = [*method]
|
296
|
+
# order is important. This check must be first since scopes can have same name as attributes!
|
297
|
+
if cache_item.value.respond_to? secured_method
|
298
|
+
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.send(secured_method, cache_item.value, @acting_user, *([*method][1..-1])) }, method, method)
|
299
|
+
elsif (cache_item.value.class < ActiveRecord::Base) && cache_item.value.attributes.has_key?(method) # TODO: second check is not needed, its built into check_permmissions, check should be does class respond to check_permissions...
|
300
|
+
cache_item.value.check_permission_with_acting_user(@acting_user, :view_permitted?, method)
|
301
|
+
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.send(*method) }, method, method)
|
302
|
+
else
|
303
|
+
raise "Method missing while fetching data: \`#{[*method].first}\` "\
|
304
|
+
'was expected to be an attribute or a method defined using the server_method of finder_method macros.'
|
305
|
+
end
|
295
306
|
end
|
296
|
-
# rescue Exception => e # this check may no longer be needed as we are quite explicit now on which methods we apply
|
297
|
-
# # ReactiveRecord::Pry::rescued(e)
|
298
|
-
# #::Rails.logger.debug "\033[0;31;1mERROR: HyperModel exception caught when applying #{method} to db object #{cache_item.value}: #{e}\033[0;30;21m"
|
299
|
-
# raise e, "HyperModel fetching records failed, exception caught when applying #{method} to db object #{cache_item.value}: #{e}", e.backtrace
|
300
307
|
end
|
301
308
|
end
|
309
|
+
rescue StandardError => e
|
310
|
+
raise e.class, form_error_message(e, cache_item.vector + error_recovery_method), e.backtrace
|
302
311
|
end
|
303
312
|
else
|
304
313
|
representative
|
@@ -306,6 +315,15 @@ module ReactiveRecord
|
|
306
315
|
end
|
307
316
|
end
|
308
317
|
|
318
|
+
def form_error_message(original_error, vector)
|
319
|
+
expression = vector.collect do |exp|
|
320
|
+
next exp unless exp.is_a? Array
|
321
|
+
next exp.first if exp.length == 1
|
322
|
+
"#{exp.first}(#{exp[1..-1].join(', ')})"
|
323
|
+
end.join('.')
|
324
|
+
"raised when evaluating #{expression}\n#{original_error}"
|
325
|
+
end
|
326
|
+
|
309
327
|
def aggregation?(method)
|
310
328
|
if method.is_a?(String) && @value.class.respond_to?(:reflect_on_aggregation)
|
311
329
|
aggregation = @value.class.reflect_on_aggregation(method.to_sym)
|
@@ -378,6 +396,8 @@ module ReactiveRecord
|
|
378
396
|
if method == "*"
|
379
397
|
if @value.is_a? Array # this happens when a scope is empty there is test case, but
|
380
398
|
@parent.as_hash({}) # does it work for all edge cases?
|
399
|
+
elsif (@value.class < ActiveRecord::Base) && children.is_a?(Hash)
|
400
|
+
@parent.as_hash({@value.id => merge_inheritance_column(children)})
|
381
401
|
else
|
382
402
|
@parent.as_hash({@value.id => children})
|
383
403
|
end
|
@@ -431,17 +451,30 @@ keys:
|
|
431
451
|
if value is a hash
|
432
452
|
=end
|
433
453
|
|
434
|
-
|
435
454
|
def self.load_from_json(tree, target = nil)
|
436
|
-
|
437
455
|
# have to process *all before any other items
|
438
456
|
# we leave the "*all" key in just for debugging purposes, and then skip it below
|
439
457
|
|
440
458
|
if sorted_collection = tree["*all"]
|
441
|
-
|
459
|
+
loaded_collection = sorted_collection.collect do |id|
|
460
|
+
ReactiveRecord::Base.find_by_id(target.proxy_association.klass, id)
|
461
|
+
end
|
462
|
+
if loaded_collection[0] && target.scope_description&.name == '___hyperstack_internal_scoped_find_by'
|
463
|
+
primary_key = target.proxy_association.klass.primary_key
|
464
|
+
attrs = target.vector[-1][1].reject { |key, _| key == primary_key }
|
465
|
+
loaded_collection[0].backing_record.sync_attributes(attrs)
|
466
|
+
end
|
467
|
+
target.replace loaded_collection
|
468
|
+
# we need to notify any observers of the collection. collection#replace
|
469
|
+
# will not notify if we are data_loading (which we are) so we will do it
|
470
|
+
# here. BUT we want the notification to occur after the current event
|
471
|
+
# completes so we wrap it a bulk_update
|
472
|
+
Hyperstack::Internal::State::Mapper.bulk_update do
|
473
|
+
Hyperstack::Internal::State::Variable.set(target, :collection, target.collection)
|
474
|
+
end
|
442
475
|
end
|
443
476
|
|
444
|
-
if id_value = tree[
|
477
|
+
if (id_value = tree[target.class.try(:primary_key)] || tree[:id]) && id_value.is_a?(Array)
|
445
478
|
target.id = id_value.first
|
446
479
|
end
|
447
480
|
tree.each do |method, value|
|
@@ -453,17 +486,16 @@ keys:
|
|
453
486
|
elsif !target
|
454
487
|
load_from_json(value, Object.const_get(method))
|
455
488
|
elsif method == "*count"
|
456
|
-
target.
|
489
|
+
target.count_state = value.first
|
457
490
|
elsif method.is_a? Integer or method =~ /^[0-9]+$/
|
458
491
|
new_target = target.push_and_update_belongs_to(method)
|
459
|
-
#target << (new_target = target.proxy_association.klass.find(method))
|
460
492
|
elsif method.is_a? Array
|
461
493
|
if method[0] == "new"
|
462
494
|
new_target = ReactiveRecord::Base.lookup_by_object_id(method[1])
|
463
495
|
elsif !(target.class < ActiveRecord::Base)
|
464
496
|
new_target = target.send(*method)
|
465
497
|
# value is an array if scope returns nil, so we destroy the bogus record
|
466
|
-
new_target.destroy
|
498
|
+
new_target.destroy && (new_target = nil) if value.is_a? Array
|
467
499
|
else
|
468
500
|
target.backing_record.update_simple_attribute([method], target.backing_record.convert(method, value.first))
|
469
501
|
end
|
@@ -474,12 +506,11 @@ keys:
|
|
474
506
|
|
475
507
|
target.send "#{method}=", value.first
|
476
508
|
elsif value.is_a? Array
|
477
|
-
|
478
|
-
|
479
|
-
target.backing_record.set_attr_value(method, value.first) unless method == :id
|
480
|
-
elsif value.is_a? Hash and value[:id] and value[:id].first and association = target.class.reflect_on_association(method)
|
509
|
+
target.send("_hyperstack_internal_setter_#{method}", value.first) unless [target.class.primary_key, :id].include? method
|
510
|
+
elsif value.is_a?(Hash) && value[:id] && value[:id].first && (association = target.class.reflect_on_association(method))
|
481
511
|
# not sure if its necessary to check the id above... is it possible to for the method to be an association but not have an id?
|
482
|
-
|
512
|
+
klass = value[:model_name] ? Object.const_get(value[:model_name].first) : association.klass
|
513
|
+
new_target = ReactiveRecord::Base.find_by_id(klass, value[:id].first)
|
483
514
|
target.send "#{method}=", new_target
|
484
515
|
elsif !(target.class < ActiveRecord::Base)
|
485
516
|
new_target = target.send(*method)
|
@@ -491,7 +522,6 @@ keys:
|
|
491
522
|
load_from_json(value, new_target) if new_target
|
492
523
|
end
|
493
524
|
rescue Exception => e
|
494
|
-
# debugger
|
495
525
|
raise e
|
496
526
|
end
|
497
527
|
end
|
data/polymorph-notes.md
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
```ruby
|
2
|
+
class Picture < ApplicationRecord
|
3
|
+
belongs_to :imageable, polymorphic: true
|
4
|
+
end
|
5
|
+
|
6
|
+
class Employee < ApplicationRecord
|
7
|
+
has_many :pictures, as: :imageable
|
8
|
+
end
|
9
|
+
|
10
|
+
class Product < ApplicationRecord
|
11
|
+
has_many :pictures, as: :imageable
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
product|employee.pictures -> works almost as normal has_many as far as Hyperstack client is concerned
|
16
|
+
imageable is the "alias" of product|employee. Its as if there is a class Imageable that is the superclass
|
17
|
+
of Product and Employee.
|
18
|
+
|
19
|
+
so has_many :pictures means the usual thing (i.e. there is a belongs_to relationship on Picture) its just that
|
20
|
+
the belongs_to will be belonging to :imageable instead of :employee or :product.
|
21
|
+
|
22
|
+
okay fine
|
23
|
+
|
24
|
+
the other way:
|
25
|
+
|
26
|
+
the problem is that picture.imageable while loading is pointing to a dummy class (sure call it Imageable)
|
27
|
+
so if we say picture.imageable.foo.bar.blat what we get is a dummy value that responds to all methods, and returns itself:
|
28
|
+
|
29
|
+
picture.imageable -> imageable123 .foo -> imageable123 .bar -> ... etc. but it is a dummy value that will cause a fetch of the actual imageable record (or nil).
|
30
|
+
|
31
|
+
.imageable should be able to leverage off of server_method.
|
32
|
+
|
33
|
+
server_method(:imageable, PolymorphicDummy.new(:imageable))
|
34
|
+
|
35
|
+
hmmmm....
|
36
|
+
|
37
|
+
really its like doing a picture.imageable.itself (?) (that may work Juuuust fine)
|
38
|
+
|
39
|
+
so picture.imageable returns this funky dummy value but does an across the wire request for picture.imageable (which should get imageable_id per a normal relationship) and also get picture.imageable_type.
|
40
|
+
|
41
|
+
|
42
|
+
start again....
|
43
|
+
|
44
|
+
what happens if we ignore (on the client) the polymorphic: and as: keys?
|
45
|
+
|
46
|
+
belongs_to :imageable
|
47
|
+
|
48
|
+
means there is a class Imageable, okay so we make one, and add has_many :pictures to it.
|
49
|
+
|
50
|
+
|
51
|
+
and again....
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
def imageable
|
55
|
+
if imageable_type.loaded? && imageable_id.loaded?
|
56
|
+
const_get(imageable_type).find(imageable_id)
|
57
|
+
else
|
58
|
+
DummyImageable.new(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
very close but will not work for cases like this:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
pic = Picture.new
|
67
|
+
employee.pictures << pic
|
68
|
+
pic.imageable # FAIL... (until its been saved)
|
69
|
+
...
|
70
|
+
```
|
71
|
+
|
72
|
+
but still it may be as simple as overriding `<<` so that it sets type on imageable. But we still to have a proper belongs to relationship.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
def imageable
|
76
|
+
if we already have the attribute set
|
77
|
+
return the attribute
|
78
|
+
else
|
79
|
+
set attribute to DummyPolyClass.new(self, 'imageable')
|
80
|
+
# DummyPolyClass init will set up a fetch of the actual imageable value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def imageable=(x)
|
85
|
+
# will it just work ?
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
its all about the collection inverse. The inverse class of the has_many is the class containing the polymorphic belongs to. But the inverse of a polymorphic belongs to depends on the value. If the value is nil or a DummyPolyClass object then there is no inverse.
|
90
|
+
|
91
|
+
I think if inverse takes this into account then `<<` and `=` should just "work" (well almost) and probably everything else will to.
|
92
|
+
|
93
|
+
### NOTES on the DummyPolyClass...
|
94
|
+
|
95
|
+
it needs to respond to reflect_on_all_associations, but just return an empty array. This way when we search for matching inverse attribute we won't find it.
|
96
|
+
|
97
|
+
### Status
|
98
|
+
|
99
|
+
added model to inverse, inverse_of, find_inverse
|
100
|
+
|
101
|
+
if the relationship is a collection then we will always know the inverse.
|
102
|
+
|
103
|
+
The only time we might no know the inverse is if its NOT a collection (i.e. belongs_to)
|
104
|
+
|
105
|
+
So only places that are applying inverse to an association that is NOT a collection do we have to pass the model in.
|
106
|
+
|
107
|
+
All inverse_of method calls have been checked and updated
|
108
|
+
|
109
|
+
that leaves inverse which is only used in SETTERS hurray!
|
110
|
+
|
111
|
+
|
112
|
+
### Latest thinking
|
113
|
+
|
114
|
+
going from `has_many / has_one as: ...` is easy its essentially setting the association foreign_key using the name supplied to the as:
|
115
|
+
|
116
|
+
The problem is going from the polymorphic belongs_to side.
|
117
|
+
|
118
|
+
We don't know the actual type we are loading which presents two problems.
|
119
|
+
|
120
|
+
First we just don't know the type. So if I say `Picture.find(1).imageable.foo.bar` I really can't do anything with foo and bar. This is solved by having a DummyPolymorph class, which responds to all missing methods with itself, and on creation sets up a vector to pull it the id, and type of the record being fetched. This will cause a second fetch to actually get `foo.bar` because we don't know what they are yet. (Its cool beacuse this is like Type inference actually, and I think we could eventually use a type inference system to get rid of the second fetch!!!)
|
121
|
+
|
122
|
+
Second we don't know the inverse of the relationship (since we don't know the type)
|
123
|
+
|
124
|
+
We can solve this by aliasing the inverse relationship (the one with the `as: SOMENAME` option) to be `has_many #{__hyperstack_polymorphic_inverse_of_#{SOMENAME}` and then defining method(s) against the relationship name. This way regardless of what the polymorphic relationship points to we know the inverse is `__hyperstack_polymorphic_inverse_of_#{SOMENAME}`.
|
125
|
+
|
126
|
+
If the inverse relationship is a has_many then we define
|
127
|
+
```ruby
|
128
|
+
def #{RELATIONSHIP_NAME}
|
129
|
+
__hyperstack_polymorphic_inverse_of_#{SOMENAME}
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
If the inverse relationship is a has_one we have to work a bit harder:
|
134
|
+
```ruby
|
135
|
+
def #{RELATIONSHIP_NAME}
|
136
|
+
__hyperstack_polymorphic_inverse_of_#{SOMENAME}[0]
|
137
|
+
end
|
138
|
+
def #{RELATIONSHIP_NAME}=(x)
|
139
|
+
__hyperstack_polymorphic_inverse_of_#{SOMENAME}[0] = x # or perhaps we have to replace the array using the internal method in collection for that purpose.
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
The remaining problem is that the server side will have no such relationships defined so we need to add the `has_many __hyperstack_polymorphic_inverse_of_#{SOMENAME} as: SOMENAME` server side.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hyper-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.alpha1.
|
4
|
+
version: 1.0.alpha1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitch VanDuyn
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-04-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -39,56 +39,36 @@ dependencies:
|
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 4.0.0
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: hyper-component
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - '='
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: 1.0.alpha1.3
|
49
|
-
type: :runtime
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - '='
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: 1.0.alpha1.3
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: hyper-operation
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
59
45
|
requirements:
|
60
46
|
- - '='
|
61
47
|
- !ruby/object:Gem::Version
|
62
|
-
version: 1.0.alpha1.
|
48
|
+
version: 1.0.alpha1.8
|
63
49
|
type: :runtime
|
64
50
|
prerelease: false
|
65
51
|
version_requirements: !ruby/object:Gem::Requirement
|
66
52
|
requirements:
|
67
53
|
- - '='
|
68
54
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.0.alpha1.
|
55
|
+
version: 1.0.alpha1.8
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
57
|
name: bundler
|
72
58
|
requirement: !ruby/object:Gem::Requirement
|
73
59
|
requirements:
|
74
60
|
- - ">="
|
75
61
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
77
|
-
- - "<"
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: '2.1'
|
62
|
+
version: '0'
|
80
63
|
type: :development
|
81
64
|
prerelease: false
|
82
65
|
version_requirements: !ruby/object:Gem::Requirement
|
83
66
|
requirements:
|
84
67
|
- - ">="
|
85
68
|
- !ruby/object:Gem::Version
|
86
|
-
version:
|
87
|
-
- - "<"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '2.1'
|
69
|
+
version: '0'
|
90
70
|
- !ruby/object:Gem::Dependency
|
91
|
-
name:
|
71
|
+
name: database_cleaner
|
92
72
|
requirement: !ruby/object:Gem::Requirement
|
93
73
|
requirements:
|
94
74
|
- - ">="
|
@@ -102,21 +82,7 @@ dependencies:
|
|
102
82
|
- !ruby/object:Gem::Version
|
103
83
|
version: '0'
|
104
84
|
- !ruby/object:Gem::Dependency
|
105
|
-
name:
|
106
|
-
requirement: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - '='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 1.2.0
|
111
|
-
type: :development
|
112
|
-
prerelease: false
|
113
|
-
version_requirements: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - '='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 1.2.0
|
118
|
-
- !ruby/object:Gem::Dependency
|
119
|
-
name: libv8
|
85
|
+
name: factory_bot_rails
|
120
86
|
requirement: !ruby/object:Gem::Requirement
|
121
87
|
requirements:
|
122
88
|
- - ">="
|
@@ -130,49 +96,35 @@ dependencies:
|
|
130
96
|
- !ruby/object:Gem::Version
|
131
97
|
version: '0'
|
132
98
|
- !ruby/object:Gem::Dependency
|
133
|
-
name:
|
99
|
+
name: hyper-spec
|
134
100
|
requirement: !ruby/object:Gem::Requirement
|
135
101
|
requirements:
|
136
|
-
- -
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.2.4
|
139
|
-
type: :development
|
140
|
-
prerelease: false
|
141
|
-
version_requirements: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 0.2.4
|
146
|
-
- !ruby/object:Gem::Dependency
|
147
|
-
name: selenium-webdriver
|
148
|
-
requirement: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
102
|
+
- - '='
|
151
103
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
104
|
+
version: 1.0.alpha1.8
|
153
105
|
type: :development
|
154
106
|
prerelease: false
|
155
107
|
version_requirements: !ruby/object:Gem::Requirement
|
156
108
|
requirements:
|
157
|
-
- -
|
109
|
+
- - '='
|
158
110
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
111
|
+
version: 1.0.alpha1.8
|
160
112
|
- !ruby/object:Gem::Dependency
|
161
|
-
name:
|
113
|
+
name: hyper-trace
|
162
114
|
requirement: !ruby/object:Gem::Requirement
|
163
115
|
requirements:
|
164
|
-
- -
|
116
|
+
- - '='
|
165
117
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
118
|
+
version: 1.0.alpha1.8
|
167
119
|
type: :development
|
168
120
|
prerelease: false
|
169
121
|
version_requirements: !ruby/object:Gem::Requirement
|
170
122
|
requirements:
|
171
|
-
- -
|
123
|
+
- - '='
|
172
124
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
125
|
+
version: 1.0.alpha1.8
|
174
126
|
- !ruby/object:Gem::Dependency
|
175
|
-
name:
|
127
|
+
name: mini_racer
|
176
128
|
requirement: !ruby/object:Gem::Requirement
|
177
129
|
requirements:
|
178
130
|
- - ">="
|
@@ -186,7 +138,7 @@ dependencies:
|
|
186
138
|
- !ruby/object:Gem::Version
|
187
139
|
version: '0'
|
188
140
|
- !ruby/object:Gem::Dependency
|
189
|
-
name:
|
141
|
+
name: pg
|
190
142
|
requirement: !ruby/object:Gem::Requirement
|
191
143
|
requirements:
|
192
144
|
- - ">="
|
@@ -199,64 +151,28 @@ dependencies:
|
|
199
151
|
- - ">="
|
200
152
|
- !ruby/object:Gem::Version
|
201
153
|
version: '0'
|
202
|
-
- !ruby/object:Gem::Dependency
|
203
|
-
name: opal-activesupport
|
204
|
-
requirement: !ruby/object:Gem::Requirement
|
205
|
-
requirements:
|
206
|
-
- - "~>"
|
207
|
-
- !ruby/object:Gem::Version
|
208
|
-
version: 0.3.1
|
209
|
-
type: :development
|
210
|
-
prerelease: false
|
211
|
-
version_requirements: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - "~>"
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: 0.3.1
|
216
|
-
- !ruby/object:Gem::Dependency
|
217
|
-
name: opal-browser
|
218
|
-
requirement: !ruby/object:Gem::Requirement
|
219
|
-
requirements:
|
220
|
-
- - "~>"
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: 0.2.0
|
223
|
-
type: :development
|
224
|
-
prerelease: false
|
225
|
-
version_requirements: !ruby/object:Gem::Requirement
|
226
|
-
requirements:
|
227
|
-
- - "~>"
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
version: 0.2.0
|
230
154
|
- !ruby/object:Gem::Dependency
|
231
155
|
name: opal-rails
|
232
156
|
requirement: !ruby/object:Gem::Requirement
|
233
157
|
requirements:
|
234
|
-
- - "
|
235
|
-
- !ruby/object:Gem::Version
|
236
|
-
version: 0.9.4
|
237
|
-
type: :development
|
238
|
-
prerelease: false
|
239
|
-
version_requirements: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - "~>"
|
158
|
+
- - ">="
|
242
159
|
- !ruby/object:Gem::Version
|
243
160
|
version: 0.9.4
|
244
|
-
-
|
245
|
-
name: parser
|
246
|
-
requirement: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - ">="
|
161
|
+
- - "<"
|
249
162
|
- !ruby/object:Gem::Version
|
250
|
-
version: '0'
|
163
|
+
version: '2.0'
|
251
164
|
type: :development
|
252
165
|
prerelease: false
|
253
166
|
version_requirements: !ruby/object:Gem::Requirement
|
254
167
|
requirements:
|
255
168
|
- - ">="
|
256
169
|
- !ruby/object:Gem::Version
|
257
|
-
version:
|
170
|
+
version: 0.9.4
|
171
|
+
- - "<"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.0'
|
258
174
|
- !ruby/object:Gem::Dependency
|
259
|
-
name: pry
|
175
|
+
name: pry-rescue
|
260
176
|
requirement: !ruby/object:Gem::Requirement
|
261
177
|
requirements:
|
262
178
|
- - ">="
|
@@ -270,7 +186,7 @@ dependencies:
|
|
270
186
|
- !ruby/object:Gem::Version
|
271
187
|
version: '0'
|
272
188
|
- !ruby/object:Gem::Dependency
|
273
|
-
name: pry-
|
189
|
+
name: pry-stack_explorer
|
274
190
|
requirement: !ruby/object:Gem::Requirement
|
275
191
|
requirements:
|
276
192
|
- - ">="
|
@@ -331,14 +247,20 @@ dependencies:
|
|
331
247
|
requirements:
|
332
248
|
- - ">="
|
333
249
|
- !ruby/object:Gem::Version
|
334
|
-
version:
|
250
|
+
version: 5.0.0
|
251
|
+
- - "<"
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: '7.0'
|
335
254
|
type: :development
|
336
255
|
prerelease: false
|
337
256
|
version_requirements: !ruby/object:Gem::Requirement
|
338
257
|
requirements:
|
339
258
|
- - ">="
|
340
259
|
- !ruby/object:Gem::Version
|
341
|
-
version:
|
260
|
+
version: 5.0.0
|
261
|
+
- - "<"
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: '7.0'
|
342
264
|
- !ruby/object:Gem::Dependency
|
343
265
|
name: rake
|
344
266
|
requirement: !ruby/object:Gem::Requirement
|
@@ -373,20 +295,6 @@ dependencies:
|
|
373
295
|
- - "<"
|
374
296
|
- !ruby/object:Gem::Version
|
375
297
|
version: 2.5.0
|
376
|
-
- !ruby/object:Gem::Dependency
|
377
|
-
name: reactrb-rails-generator
|
378
|
-
requirement: !ruby/object:Gem::Requirement
|
379
|
-
requirements:
|
380
|
-
- - ">="
|
381
|
-
- !ruby/object:Gem::Version
|
382
|
-
version: '0'
|
383
|
-
type: :development
|
384
|
-
prerelease: false
|
385
|
-
version_requirements: !ruby/object:Gem::Requirement
|
386
|
-
requirements:
|
387
|
-
- - ">="
|
388
|
-
- !ruby/object:Gem::Version
|
389
|
-
version: '0'
|
390
298
|
- !ruby/object:Gem::Dependency
|
391
299
|
name: rspec-collection_matchers
|
392
300
|
requirement: !ruby/object:Gem::Requirement
|
@@ -489,16 +397,16 @@ dependencies:
|
|
489
397
|
name: rubocop
|
490
398
|
requirement: !ruby/object:Gem::Requirement
|
491
399
|
requirements:
|
492
|
-
- - "
|
400
|
+
- - ">="
|
493
401
|
- !ruby/object:Gem::Version
|
494
|
-
version: 0
|
402
|
+
version: '0'
|
495
403
|
type: :development
|
496
404
|
prerelease: false
|
497
405
|
version_requirements: !ruby/object:Gem::Requirement
|
498
406
|
requirements:
|
499
|
-
- - "
|
407
|
+
- - ">="
|
500
408
|
- !ruby/object:Gem::Version
|
501
|
-
version: 0
|
409
|
+
version: '0'
|
502
410
|
- !ruby/object:Gem::Dependency
|
503
411
|
name: shoulda
|
504
412
|
requirement: !ruby/object:Gem::Requirement
|
@@ -531,30 +439,30 @@ dependencies:
|
|
531
439
|
name: spring-commands-rspec
|
532
440
|
requirement: !ruby/object:Gem::Requirement
|
533
441
|
requirements:
|
534
|
-
- - "
|
442
|
+
- - "~>"
|
535
443
|
- !ruby/object:Gem::Version
|
536
|
-
version:
|
444
|
+
version: 1.0.4
|
537
445
|
type: :development
|
538
446
|
prerelease: false
|
539
447
|
version_requirements: !ruby/object:Gem::Requirement
|
540
448
|
requirements:
|
541
|
-
- - "
|
449
|
+
- - "~>"
|
542
450
|
- !ruby/object:Gem::Version
|
543
|
-
version:
|
451
|
+
version: 1.0.4
|
544
452
|
- !ruby/object:Gem::Dependency
|
545
453
|
name: sqlite3
|
546
454
|
requirement: !ruby/object:Gem::Requirement
|
547
455
|
requirements:
|
548
|
-
- - "
|
456
|
+
- - "~>"
|
549
457
|
- !ruby/object:Gem::Version
|
550
|
-
version:
|
458
|
+
version: 1.4.2
|
551
459
|
type: :development
|
552
460
|
prerelease: false
|
553
461
|
version_requirements: !ruby/object:Gem::Requirement
|
554
462
|
requirements:
|
555
|
-
- - "
|
463
|
+
- - "~>"
|
556
464
|
- !ruby/object:Gem::Version
|
557
|
-
version:
|
465
|
+
version: 1.4.2
|
558
466
|
- !ruby/object:Gem::Dependency
|
559
467
|
name: timecop
|
560
468
|
requirement: !ruby/object:Gem::Requirement
|
@@ -569,20 +477,6 @@ dependencies:
|
|
569
477
|
- - "~>"
|
570
478
|
- !ruby/object:Gem::Version
|
571
479
|
version: 0.8.1
|
572
|
-
- !ruby/object:Gem::Dependency
|
573
|
-
name: unparser
|
574
|
-
requirement: !ruby/object:Gem::Requirement
|
575
|
-
requirements:
|
576
|
-
- - ">="
|
577
|
-
- !ruby/object:Gem::Version
|
578
|
-
version: '0'
|
579
|
-
type: :development
|
580
|
-
prerelease: false
|
581
|
-
version_requirements: !ruby/object:Gem::Requirement
|
582
|
-
requirements:
|
583
|
-
- - ">="
|
584
|
-
- !ruby/object:Gem::Version
|
585
|
-
version: '0'
|
586
480
|
description: HyperModel gives your HyperComponents CRUD access to your ActiveRecord
|
587
481
|
models on the client, using the the standard ActiveRecord API. HyperModel also implements
|
588
482
|
push notifications (via a number of possible technologies) so changes to records
|
@@ -598,7 +492,6 @@ files:
|
|
598
492
|
- ".rspec"
|
599
493
|
- ".travis.yml"
|
600
494
|
- Gemfile
|
601
|
-
- Gemfile.lock
|
602
495
|
- Rakefile
|
603
496
|
- bin/console
|
604
497
|
- bin/setup
|
@@ -629,6 +522,7 @@ files:
|
|
629
522
|
- lib/reactive_record/active_record/reactive_record/base.rb
|
630
523
|
- lib/reactive_record/active_record/reactive_record/collection.rb
|
631
524
|
- lib/reactive_record/active_record/reactive_record/column_types.rb
|
525
|
+
- lib/reactive_record/active_record/reactive_record/dummy_polymorph.rb
|
632
526
|
- lib/reactive_record/active_record/reactive_record/dummy_value.rb
|
633
527
|
- lib/reactive_record/active_record/reactive_record/getters.rb
|
634
528
|
- lib/reactive_record/active_record/reactive_record/isomorphic_base.rb
|
@@ -648,6 +542,7 @@ files:
|
|
648
542
|
- lib/reactive_record/scope_description.rb
|
649
543
|
- lib/reactive_record/serializers.rb
|
650
544
|
- lib/reactive_record/server_data_cache.rb
|
545
|
+
- polymorph-notes.md
|
651
546
|
- spec_fails.txt
|
652
547
|
homepage: http://ruby-hyperstack.org
|
653
548
|
licenses:
|
@@ -668,7 +563,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
668
563
|
- !ruby/object:Gem::Version
|
669
564
|
version: 1.3.1
|
670
565
|
requirements: []
|
671
|
-
rubygems_version: 3.0.
|
566
|
+
rubygems_version: 3.0.8
|
672
567
|
signing_key:
|
673
568
|
specification_version: 4
|
674
569
|
summary: React based CRUD access and Synchronization of active record models across
|