hyper-model 1.0.alpha1.2 → 1.0.alpha1.3
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/Gemfile.lock +44 -25
- data/Rakefile +12 -0
- data/hyper-model.gemspec +3 -3
- data/lib/active_record_base.rb +10 -5
- data/lib/hyper_model/version.rb +1 -1
- data/lib/reactive_record/active_record/associations.rb +10 -4
- data/lib/reactive_record/active_record/class_methods.rb +2 -2
- data/lib/reactive_record/active_record/reactive_record/collection.rb +31 -6
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +12 -9
- data/lib/reactive_record/active_record/reactive_record/operations.rb +3 -2
- data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +7 -1
- data/lib/reactive_record/active_record/reactive_record/while_loading.rb +228 -32
- data/lib/reactive_record/broadcast.rb +4 -1
- data/lib/reactive_record/permissions.rb +14 -2
- data/lib/reactive_record/server_data_cache.rb +28 -8
- data/spec_fails.txt +3 -0
- metadata +22 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 071e8cc562ebddf1c0a260587a123d91db9f2a7c52d43b06fcf063079d66129f
|
|
4
|
+
data.tar.gz: 4cb7539129b7367f3156c0726ac3ed164e1db391f7806457253d303e9940941c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c1bcd8fee396593e2f31d072f35cbf88467be2b02c198d523c052b67a211d9fea4501ca86c4f0a388cee35bc34f4ac9156147a13aac9aec4842616a5c3c1772
|
|
7
|
+
data.tar.gz: c226e31b1882e96c8a7a080114aea90aacdb0bb77331fc36854f79fe118fabd119f278bc20b94d3693bcc69d7382bc6e4d2f1e91c042b41eb660d2214e75c45d
|
data/Gemfile.lock
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ../hyper-component
|
|
3
3
|
specs:
|
|
4
|
-
hyper-component (1.0.alpha1.
|
|
5
|
-
hyper-state (= 1.0.alpha1.
|
|
6
|
-
hyperstack-config (= 1.0.alpha1.
|
|
7
|
-
libv8 (~> 6.
|
|
8
|
-
mini_racer (~> 0.
|
|
4
|
+
hyper-component (1.0.alpha1.3)
|
|
5
|
+
hyper-state (= 1.0.alpha1.3)
|
|
6
|
+
hyperstack-config (= 1.0.alpha1.3)
|
|
7
|
+
libv8 (~> 6.7.0)
|
|
8
|
+
mini_racer (~> 0.2.4)
|
|
9
9
|
opal (>= 0.11.0, < 0.12.0)
|
|
10
10
|
opal-activesupport (~> 0.3.1)
|
|
11
11
|
react-rails (>= 2.4.0, < 2.5.0)
|
|
@@ -13,26 +13,26 @@ PATH
|
|
|
13
13
|
PATH
|
|
14
14
|
remote: ../hyper-operation
|
|
15
15
|
specs:
|
|
16
|
-
hyper-operation (1.0.alpha1.
|
|
16
|
+
hyper-operation (1.0.alpha1.3)
|
|
17
17
|
activerecord (>= 4.0.0)
|
|
18
|
-
hyper-component (= 1.0.alpha1.
|
|
18
|
+
hyper-component (= 1.0.alpha1.3)
|
|
19
19
|
mutations
|
|
20
20
|
opal-activesupport (~> 0.3.1)
|
|
21
|
+
tty-table
|
|
21
22
|
|
|
22
23
|
PATH
|
|
23
24
|
remote: ../hyper-state
|
|
24
25
|
specs:
|
|
25
|
-
hyper-state (1.0.alpha1.
|
|
26
|
-
hyperstack-config (= 1.0.alpha1.
|
|
26
|
+
hyper-state (1.0.alpha1.3)
|
|
27
|
+
hyperstack-config (= 1.0.alpha1.3)
|
|
27
28
|
opal (>= 0.11.0, < 0.12.0)
|
|
28
29
|
|
|
29
30
|
PATH
|
|
30
31
|
remote: ../hyperstack-config
|
|
31
32
|
specs:
|
|
32
|
-
hyperstack-config (1.0.alpha1.
|
|
33
|
-
libv8 (~> 6.3.0)
|
|
33
|
+
hyperstack-config (1.0.alpha1.3)
|
|
34
34
|
listen (~> 3.0)
|
|
35
|
-
mini_racer (~> 0.
|
|
35
|
+
mini_racer (~> 0.2.4)
|
|
36
36
|
opal (>= 0.11.0, < 0.12.0)
|
|
37
37
|
opal-browser (~> 0.2.0)
|
|
38
38
|
uglifier
|
|
@@ -41,11 +41,11 @@ PATH
|
|
|
41
41
|
PATH
|
|
42
42
|
remote: .
|
|
43
43
|
specs:
|
|
44
|
-
hyper-model (1.0.alpha1.
|
|
44
|
+
hyper-model (1.0.alpha1.3)
|
|
45
45
|
activemodel
|
|
46
46
|
activerecord (>= 4.0.0)
|
|
47
|
-
hyper-component (= 1.0.alpha1.
|
|
48
|
-
hyper-operation (= 1.0.alpha1.
|
|
47
|
+
hyper-component (= 1.0.alpha1.3)
|
|
48
|
+
hyper-operation (= 1.0.alpha1.3)
|
|
49
49
|
|
|
50
50
|
GEM
|
|
51
51
|
remote: https://rubygems.org/
|
|
@@ -141,6 +141,7 @@ GEM
|
|
|
141
141
|
eventmachine (>= 0.12.9)
|
|
142
142
|
http_parser.rb (~> 0.6.0)
|
|
143
143
|
equalizer (0.0.11)
|
|
144
|
+
equatable (0.5.0)
|
|
144
145
|
erubi (1.7.1)
|
|
145
146
|
eventmachine (1.2.7)
|
|
146
147
|
execjs (2.7.0)
|
|
@@ -164,7 +165,7 @@ GEM
|
|
|
164
165
|
rails-dom-testing (>= 1, < 3)
|
|
165
166
|
railties (>= 4.2.0)
|
|
166
167
|
thor (>= 0.14, < 2.0)
|
|
167
|
-
libv8 (6.
|
|
168
|
+
libv8 (6.7.288.46.1)
|
|
168
169
|
listen (3.1.5)
|
|
169
170
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
170
171
|
rb-inotify (~> 0.9, >= 0.9.7)
|
|
@@ -182,13 +183,14 @@ GEM
|
|
|
182
183
|
mimemagic (0.3.2)
|
|
183
184
|
mini_mime (1.0.1)
|
|
184
185
|
mini_portile2 (2.3.0)
|
|
185
|
-
mini_racer (0.
|
|
186
|
-
libv8 (
|
|
186
|
+
mini_racer (0.2.4)
|
|
187
|
+
libv8 (>= 6.3)
|
|
187
188
|
minitest (5.11.3)
|
|
188
189
|
multi_json (1.13.1)
|
|
189
190
|
mutations (0.8.3)
|
|
190
191
|
activesupport
|
|
191
192
|
mysql2 (0.5.2)
|
|
193
|
+
necromancer (0.4.0)
|
|
192
194
|
nio4r (2.3.1)
|
|
193
195
|
nokogiri (1.8.4)
|
|
194
196
|
mini_portile2 (~> 2.3.0)
|
|
@@ -220,6 +222,9 @@ GEM
|
|
|
220
222
|
parallel (1.12.1)
|
|
221
223
|
parser (2.3.3.1)
|
|
222
224
|
ast (~> 2.2)
|
|
225
|
+
pastel (0.7.2)
|
|
226
|
+
equatable (~> 0.5.0)
|
|
227
|
+
tty-color (~> 0.4.0)
|
|
223
228
|
powerpack (0.1.2)
|
|
224
229
|
procto (0.0.3)
|
|
225
230
|
pry (0.11.3)
|
|
@@ -271,8 +276,8 @@ GEM
|
|
|
271
276
|
rake
|
|
272
277
|
rake (12.3.1)
|
|
273
278
|
rb-fsevent (0.10.3)
|
|
274
|
-
rb-inotify (0.
|
|
275
|
-
ffi (
|
|
279
|
+
rb-inotify (0.10.0)
|
|
280
|
+
ffi (~> 1.0)
|
|
276
281
|
react-rails (2.4.7)
|
|
277
282
|
babel-transpiler (>= 0.7.0)
|
|
278
283
|
connection_pool
|
|
@@ -343,6 +348,11 @@ GEM
|
|
|
343
348
|
activesupport (>= 4.0)
|
|
344
349
|
sprockets (>= 3.0.0)
|
|
345
350
|
sqlite3 (1.3.13)
|
|
351
|
+
strings (0.1.4)
|
|
352
|
+
strings-ansi (~> 0.1.0)
|
|
353
|
+
unicode-display_width (~> 1.4.0)
|
|
354
|
+
unicode_utils (~> 1.4.0)
|
|
355
|
+
strings-ansi (0.1.0)
|
|
346
356
|
thin (1.7.2)
|
|
347
357
|
daemons (~> 1.0, >= 1.0.9)
|
|
348
358
|
eventmachine (~> 1.0, >= 1.0.4)
|
|
@@ -351,11 +361,20 @@ GEM
|
|
|
351
361
|
thread_safe (0.3.6)
|
|
352
362
|
tilt (2.0.8)
|
|
353
363
|
timecop (0.8.1)
|
|
364
|
+
tty-color (0.4.3)
|
|
365
|
+
tty-screen (0.6.5)
|
|
366
|
+
tty-table (0.10.0)
|
|
367
|
+
equatable (~> 0.5.0)
|
|
368
|
+
necromancer (~> 0.4.0)
|
|
369
|
+
pastel (~> 0.7.2)
|
|
370
|
+
strings (~> 0.1.0)
|
|
371
|
+
tty-screen (~> 0.6.4)
|
|
354
372
|
tzinfo (1.2.5)
|
|
355
373
|
thread_safe (~> 0.1)
|
|
356
|
-
uglifier (4.1.
|
|
374
|
+
uglifier (4.1.20)
|
|
357
375
|
execjs (>= 0.3.0, < 3)
|
|
358
376
|
unicode-display_width (1.4.0)
|
|
377
|
+
unicode_utils (1.4.0)
|
|
359
378
|
unparser (0.2.8)
|
|
360
379
|
abstract_type (~> 0.0.7)
|
|
361
380
|
adamantium (~> 0.2.0)
|
|
@@ -375,7 +394,7 @@ PLATFORMS
|
|
|
375
394
|
ruby
|
|
376
395
|
|
|
377
396
|
DEPENDENCIES
|
|
378
|
-
bundler
|
|
397
|
+
bundler (>= 1.17.3, < 2.1)
|
|
379
398
|
capybara
|
|
380
399
|
chromedriver-helper (= 1.2.0)
|
|
381
400
|
database_cleaner
|
|
@@ -385,8 +404,8 @@ DEPENDENCIES
|
|
|
385
404
|
hyper-operation!
|
|
386
405
|
hyper-state!
|
|
387
406
|
hyperstack-config!
|
|
388
|
-
libv8
|
|
389
|
-
mini_racer (~> 0.
|
|
407
|
+
libv8
|
|
408
|
+
mini_racer (~> 0.2.4)
|
|
390
409
|
mysql2
|
|
391
410
|
opal-activesupport (~> 0.3.1)
|
|
392
411
|
opal-browser (~> 0.2.0)
|
|
@@ -418,4 +437,4 @@ DEPENDENCIES
|
|
|
418
437
|
unparser
|
|
419
438
|
|
|
420
439
|
BUNDLED WITH
|
|
421
|
-
|
|
440
|
+
2.0.1
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
|
3
3
|
|
|
4
|
+
task :part1 do
|
|
5
|
+
(1..2).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
task :part2 do
|
|
9
|
+
(3..4).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
task :part3 do
|
|
13
|
+
(5..7).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
|
|
14
|
+
end
|
|
15
|
+
|
|
4
16
|
task :spec do
|
|
5
17
|
(1..7).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
|
|
6
18
|
end
|
data/hyper-model.gemspec
CHANGED
|
@@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_dependency 'activerecord', '>= 4.0.0'
|
|
30
30
|
spec.add_dependency 'hyper-component', HyperModel::VERSION
|
|
31
31
|
spec.add_dependency 'hyper-operation', HyperModel::VERSION
|
|
32
|
-
spec.add_development_dependency 'bundler'
|
|
32
|
+
spec.add_development_dependency 'bundler', ['>= 1.17.3', '< 2.1']
|
|
33
33
|
spec.add_development_dependency 'capybara'
|
|
34
34
|
spec.add_development_dependency 'chromedriver-helper', '1.2.0'
|
|
35
|
-
spec.add_development_dependency 'libv8'
|
|
36
|
-
spec.add_development_dependency 'mini_racer', '~> 0.
|
|
35
|
+
spec.add_development_dependency 'libv8'
|
|
36
|
+
spec.add_development_dependency 'mini_racer', '~> 0.2.4'
|
|
37
37
|
spec.add_development_dependency 'selenium-webdriver'
|
|
38
38
|
spec.add_development_dependency 'database_cleaner'
|
|
39
39
|
spec.add_development_dependency 'factory_bot_rails'
|
data/lib/active_record_base.rb
CHANGED
|
@@ -29,7 +29,7 @@ module ActiveRecord
|
|
|
29
29
|
class ReactiveRecordPsuedoRelationArray < Array
|
|
30
30
|
attr_accessor :__synchromesh_permission_granted
|
|
31
31
|
attr_accessor :acting_user
|
|
32
|
-
def __secure_collection_check(
|
|
32
|
+
def __secure_collection_check(*)
|
|
33
33
|
self
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -39,11 +39,13 @@ module ActiveRecord
|
|
|
39
39
|
class Relation
|
|
40
40
|
attr_accessor :__synchromesh_permission_granted
|
|
41
41
|
attr_accessor :acting_user
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
def __secure_collection_check(cache_item)
|
|
43
44
|
return self if __synchromesh_permission_granted
|
|
44
|
-
return self if __secure_remote_access_to_all(self, acting_user).__synchromesh_permission_granted
|
|
45
|
-
return self if __secure_remote_access_to_unscoped(self, acting_user).__synchromesh_permission_granted
|
|
46
|
-
Hyperstack::InternalPolicy.raise_operation_access_violation(
|
|
45
|
+
return self if __secure_remote_access_to_all(self, cache_item.acting_user).__synchromesh_permission_granted
|
|
46
|
+
return self if __secure_remote_access_to_unscoped(self, cache_item.acting_user).__synchromesh_permission_granted
|
|
47
|
+
Hyperstack::InternalPolicy.raise_operation_access_violation(
|
|
48
|
+
:scoped_permission_not_granted, "Access denied for #{cache_item}")
|
|
47
49
|
end
|
|
48
50
|
end
|
|
49
51
|
# Monkey patches and extensions to base
|
|
@@ -90,6 +92,9 @@ module ActiveRecord
|
|
|
90
92
|
this.acting_user = old
|
|
91
93
|
end
|
|
92
94
|
end
|
|
95
|
+
singleton_class.send(:define_method, "_#{name}") do |*args|
|
|
96
|
+
all.instance_exec(*args, &block)
|
|
97
|
+
end
|
|
93
98
|
singleton_class.send(:define_method, name) do |*args|
|
|
94
99
|
all.instance_exec(*args, &block)
|
|
95
100
|
end
|
data/lib/hyper_model/version.rb
CHANGED
|
@@ -44,7 +44,7 @@ module ActiveRecord
|
|
|
44
44
|
@owner_class = owner_class
|
|
45
45
|
@macro = macro
|
|
46
46
|
@options = options
|
|
47
|
-
@klass_name = options[:class_name] || (collection? && name.camelize.
|
|
47
|
+
@klass_name = options[:class_name] || (collection? && name.camelize.singularize) || name.camelize
|
|
48
48
|
@association_foreign_key = options[:foreign_key] || (macro == :belongs_to && "#{name}_id") || "#{@owner_class.name.underscore}_id"
|
|
49
49
|
@source = options[:source] || @klass_name.underscore if options[:through]
|
|
50
50
|
@attribute = name
|
|
@@ -97,9 +97,15 @@ module ActiveRecord
|
|
|
97
97
|
next if association.attribute == attribute
|
|
98
98
|
return association if klass == association.owner_class
|
|
99
99
|
end
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
# instead of raising an error go ahead and create the inverse relationship if it does not exist.
|
|
101
|
+
# https://github.com/hyperstack-org/hyperstack/issues/89
|
|
102
|
+
if macro == :belongs_to
|
|
103
|
+
Hyperstack::Component::IsomorphicHelpers.log "**** warning dynamically adding relationship: #{klass}.has_many :#{@owner_class.name.underscore.pluralize}, foreign_key: #{@association_foreign_key}", :warning
|
|
104
|
+
klass.has_many @owner_class.name.underscore.pluralize, foreign_key: @association_foreign_key
|
|
105
|
+
else
|
|
106
|
+
Hyperstack::Component::IsomorphicHelpers.log "**** warning dynamically adding relationship: #{klass}.belongs_to :#{@owner_class.name.underscore}, foreign_key: #{@association_foreign_key}", :warning
|
|
107
|
+
klass.belongs_to @owner_class.name.underscore, foreign_key: @association_foreign_key
|
|
108
|
+
end
|
|
103
109
|
end
|
|
104
110
|
|
|
105
111
|
def klass
|
|
@@ -261,10 +261,10 @@ module ActiveRecord
|
|
|
261
261
|
end
|
|
262
262
|
|
|
263
263
|
def finder_method(name)
|
|
264
|
-
ReactiveRecord::ScopeDescription.new(self, "_#{name}", {})
|
|
264
|
+
ReactiveRecord::ScopeDescription.new(self, "_#{name}", {}) # was adding _ to front
|
|
265
265
|
[name, "#{name}!"].each do |method|
|
|
266
266
|
singleton_class.send(:define_method, method) do |*vargs|
|
|
267
|
-
all.apply_scope("_#{method}", *vargs).first
|
|
267
|
+
all.apply_scope("_#{method}", *vargs).first # was adding _ to front
|
|
268
268
|
end
|
|
269
269
|
end
|
|
270
270
|
end
|
|
@@ -52,6 +52,9 @@ module ReactiveRecord
|
|
|
52
52
|
def all
|
|
53
53
|
observed
|
|
54
54
|
@dummy_collection.notify if @dummy_collection
|
|
55
|
+
# unless false && @collection # this fixes https://github.com/hyperstack-org/hyperstack/issues/82 in very limited cases, and breaks otherthings
|
|
56
|
+
# sync_collection_with_parent
|
|
57
|
+
# end
|
|
55
58
|
unless @collection
|
|
56
59
|
@collection = []
|
|
57
60
|
if ids = ReactiveRecord::Base.fetch_from_db([*@vector, "*all"])
|
|
@@ -80,8 +83,15 @@ module ReactiveRecord
|
|
|
80
83
|
|
|
81
84
|
def ==(other_collection)
|
|
82
85
|
observed
|
|
83
|
-
|
|
86
|
+
# handle special case of other_collection NOT being a collection (typically nil)
|
|
87
|
+
return (@collection || []) == other_collection unless other_collection.is_a? Collection
|
|
84
88
|
other_collection.observed
|
|
89
|
+
# if either collection has not been created then compare the vectors
|
|
90
|
+
# https://github.com/hyperstack-org/hyperstack/issues/81
|
|
91
|
+
# TODO: if this works then remove the || [] below (2 of them)
|
|
92
|
+
if !@collection || !other_collection.collection
|
|
93
|
+
return @vector == other_collection.vector && unsaved_children == other_collection.unsaved_children
|
|
94
|
+
end
|
|
85
95
|
my_children = (@collection || []).select { |target| target != @dummy_record }
|
|
86
96
|
if other_collection
|
|
87
97
|
other_children = (other_collection.collection || []).select { |target| target != other_collection.dummy_record }
|
|
@@ -261,11 +271,15 @@ To determine this sync_scopes first asks if the record being changed is in the s
|
|
|
261
271
|
end
|
|
262
272
|
|
|
263
273
|
def link_to_parent
|
|
264
|
-
|
|
274
|
+
# puts "#{self}.link_to_parent @linked = #{!!@linked}, collection? #{!!@collection}"
|
|
275
|
+
# always check that parent is synced - fixes issue https://github.com/hyperstack-org/hyperstack/issues/82
|
|
276
|
+
# note that sync_collection_with_parent checks to make sure that is NOT a collection and that there IS a parent
|
|
277
|
+
|
|
278
|
+
return sync_collection_with_parent if @linked
|
|
265
279
|
@linked = true
|
|
266
280
|
if @parent
|
|
267
281
|
@parent.link_child self
|
|
268
|
-
sync_collection_with_parent
|
|
282
|
+
sync_collection_with_parent
|
|
269
283
|
else
|
|
270
284
|
ReactiveRecord::Base.add_to_outer_scopes self
|
|
271
285
|
end
|
|
@@ -278,14 +292,23 @@ To determine this sync_scopes first asks if the record being changed is in the s
|
|
|
278
292
|
end
|
|
279
293
|
|
|
280
294
|
def sync_collection_with_parent
|
|
295
|
+
# puts "#{self}.sync_collection_with_parent"
|
|
296
|
+
return if @collection || !@parent || @parent.dummy_collection # fixes issue https://github.com/hyperstack-org/hyperstack/issues/78 and supports /82
|
|
281
297
|
if @parent.collection
|
|
298
|
+
# puts ">>> @parent.collection present"
|
|
282
299
|
if @parent.collection.empty?
|
|
300
|
+
# puts ">>>>> @parent.collection is empty!"
|
|
283
301
|
@collection = []
|
|
284
302
|
elsif filter?
|
|
285
|
-
@
|
|
303
|
+
# puts "#{self}.sync_collection_with_parent (@parent = #{@parent}) calling filter records on (#{@parent.collection})"
|
|
304
|
+
@collection = filter_records(@parent.collection) # .tap { |rr| puts "returns #{rr} #{rr.to_a}" }
|
|
286
305
|
end
|
|
287
|
-
elsif @parent._count_internal(false).zero?
|
|
306
|
+
elsif !@linked && @parent._count_internal(false).zero?
|
|
307
|
+
# don't check _count_internal if already linked as this cause an unnecessary rendering cycle
|
|
308
|
+
# puts ">>> @parent._count_internal(false).zero? is true!"
|
|
288
309
|
@count = 0
|
|
310
|
+
else
|
|
311
|
+
# puts ">>> NOP"
|
|
289
312
|
end
|
|
290
313
|
end
|
|
291
314
|
|
|
@@ -327,7 +350,9 @@ To determine this sync_scopes first asks if the record being changed is in the s
|
|
|
327
350
|
# when count is called on a leaf, count_internal is called for each
|
|
328
351
|
# ancestor. Only the outermost count has load_from_client == true
|
|
329
352
|
observed
|
|
330
|
-
if @
|
|
353
|
+
if @count && @dummy_collection
|
|
354
|
+
@count # fixes https://github.com/hyperstack-org/hyperstack/issues/79
|
|
355
|
+
elsif @collection
|
|
331
356
|
@collection.count
|
|
332
357
|
elsif @count ||= ReactiveRecord::Base.fetch_from_db([*@vector, "*count"])
|
|
333
358
|
@count
|
|
@@ -10,6 +10,7 @@ module ReactiveRecord
|
|
|
10
10
|
if RUBY_ENGINE != 'opal'
|
|
11
11
|
@server_data_cache = ReactiveRecord::ServerDataCache.new(context.controller.acting_user, {})
|
|
12
12
|
else
|
|
13
|
+
Hyperstack::Internal::State::Variable.set(WhileLoading, :quiet, true)
|
|
13
14
|
@public_columns_hash = get_public_columns_hash
|
|
14
15
|
define_attribute_methods
|
|
15
16
|
@outer_scopes = Set.new
|
|
@@ -242,7 +243,7 @@ module ReactiveRecord
|
|
|
242
243
|
end if record.new? || record.changed? || (record == record_being_saved && force)
|
|
243
244
|
record_index += 1
|
|
244
245
|
end
|
|
245
|
-
[models, associations, backing_records]
|
|
246
|
+
[models.sort_by { |model| model[:id] }, associations, backing_records]
|
|
246
247
|
end
|
|
247
248
|
|
|
248
249
|
def save_or_validate(save, validate, force, &block)
|
|
@@ -316,21 +317,23 @@ module ReactiveRecord
|
|
|
316
317
|
|
|
317
318
|
else
|
|
318
319
|
|
|
319
|
-
def self.find_record(model, id, vector, save)
|
|
320
|
+
def self.find_record(model, id, acting_user, vector, save)
|
|
320
321
|
if !save
|
|
321
322
|
found = vector[1..-1].inject(vector[0]) do |object, method|
|
|
322
323
|
if object.nil? # happens if you try to do an all on empty scope followed by more scopes
|
|
323
324
|
object
|
|
324
|
-
elsif method.is_a? Array
|
|
325
|
+
elsif method.is_a? Array #__secure_remote_access_to_
|
|
325
326
|
if method[0] == 'new'
|
|
326
327
|
object.new
|
|
327
|
-
|
|
328
|
+
elsif method[0] == 'find_by'
|
|
328
329
|
object.send(*method)
|
|
330
|
+
else
|
|
331
|
+
object.send(:"__secure_remote_access_to_#{method[0]}", object, acting_user, *method[1..-1])
|
|
329
332
|
end
|
|
330
|
-
elsif method.is_a?
|
|
333
|
+
elsif method.is_a?(String) && method[0] == '*'
|
|
331
334
|
object[method.gsub(/^\*/,'').to_i]
|
|
332
335
|
else
|
|
333
|
-
object.send(method)
|
|
336
|
+
object.send(:"__secure_remote_access_to_#{method}", object, acting_user)
|
|
334
337
|
end
|
|
335
338
|
end
|
|
336
339
|
if id and (found.nil? or !(found.class <= model) or (found.id and found.id.to_s != id.to_s))
|
|
@@ -362,13 +365,13 @@ module ReactiveRecord
|
|
|
362
365
|
id = attributes.delete(model.primary_key) if model.respond_to? :primary_key # if we are saving existing model primary key value will be present
|
|
363
366
|
vector = model_to_save[:vector]
|
|
364
367
|
vector = [vector[0].constantize] + vector[1..-1].collect do |method|
|
|
365
|
-
if method.is_a?(Array)
|
|
368
|
+
if method.is_a?(Array) && method.first == "find_by_id"
|
|
366
369
|
["find", method.last]
|
|
367
370
|
else
|
|
368
371
|
method
|
|
369
372
|
end
|
|
370
373
|
end
|
|
371
|
-
reactive_records[model_to_save[:id]] = vectors[vector] = record = find_record(model, id, vector, save) # ??? || validate ???
|
|
374
|
+
reactive_records[model_to_save[:id]] = vectors[vector] = record = find_record(model, id, acting_user, vector, save) # ??? || validate ???
|
|
372
375
|
next unless record
|
|
373
376
|
if attributes.empty?
|
|
374
377
|
dont_save_list << record unless save
|
|
@@ -507,7 +510,7 @@ module ReactiveRecord
|
|
|
507
510
|
if save || validate
|
|
508
511
|
{success: false, saved_models: saved_models, message: e}
|
|
509
512
|
else
|
|
510
|
-
{}
|
|
513
|
+
raise e # was returning {} TODO verify that just raising the error at least reports the error
|
|
511
514
|
end
|
|
512
515
|
end
|
|
513
516
|
|
|
@@ -65,8 +65,9 @@ module ReactiveRecord
|
|
|
65
65
|
]
|
|
66
66
|
end
|
|
67
67
|
failed do |e|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
e.define_singleton_method(:__hyperstack_on_error) do |operation, params, fmted_message|
|
|
69
|
+
Hyperstack.on_error(operation, self, params, fmted_message)
|
|
70
|
+
end
|
|
70
71
|
raise e
|
|
71
72
|
end
|
|
72
73
|
end
|
|
@@ -9,7 +9,10 @@ module ReactiveRecord
|
|
|
9
9
|
def set_pre_sync_related_records(related_records, _record = nil)
|
|
10
10
|
@pre_sync_related_records = nil
|
|
11
11
|
ReactiveRecord::Base.catch_db_requests do
|
|
12
|
+
puts "#{self}.set_pre_sync_related_records filter_records(#{related_records})"
|
|
13
|
+
|
|
12
14
|
@pre_sync_related_records = filter_records(related_records)
|
|
15
|
+
puts "returns #{@pre_sync_related_records}"
|
|
13
16
|
live_scopes.each do |scope|
|
|
14
17
|
scope.set_pre_sync_related_records(@pre_sync_related_records)
|
|
15
18
|
end
|
|
@@ -32,7 +35,9 @@ module ReactiveRecord
|
|
|
32
35
|
if collector?
|
|
33
36
|
update_collector_scope(related_records)
|
|
34
37
|
else
|
|
38
|
+
puts "#{self}.update_collection calling filter_records(#{related_records})"
|
|
35
39
|
related_records = filter_records(related_records)
|
|
40
|
+
puts "returns #{related_records}"
|
|
36
41
|
update_filter_scope(@pre_sync_related_records, related_records)
|
|
37
42
|
end
|
|
38
43
|
end
|
|
@@ -41,7 +46,8 @@ module ReactiveRecord
|
|
|
41
46
|
current = Set.new([*@collection])
|
|
42
47
|
(related_records - @pre_sync_related_records).each { |r| current << r }
|
|
43
48
|
(@pre_sync_related_records - related_records).each { |r| current.delete(r) }
|
|
44
|
-
replace(filter_records(current))
|
|
49
|
+
puts "#{self}.update_collector_scope calling replace(filter_records(#{current}))"
|
|
50
|
+
replace(filter_records(current).tap { |rr| puts "returns #{rr}" })
|
|
45
51
|
Set.new([*@collection])
|
|
46
52
|
end
|
|
47
53
|
|
|
@@ -74,6 +74,191 @@ module ReactiveRecord
|
|
|
74
74
|
# To notify React that something is loading use React::WhileLoading.loading!
|
|
75
75
|
# once everything is loaded then do React::WhileLoading.loaded_at message (typically a time stamp just for debug purposes)
|
|
76
76
|
|
|
77
|
+
# class WhileLoading
|
|
78
|
+
#
|
|
79
|
+
# include Hyperstack::Component::IsomorphicHelpers
|
|
80
|
+
#
|
|
81
|
+
# before_first_mount do
|
|
82
|
+
# @css_to_preload = ""
|
|
83
|
+
# @while_loading_counter = 0
|
|
84
|
+
# end
|
|
85
|
+
#
|
|
86
|
+
# def self.get_next_while_loading_counter
|
|
87
|
+
# @while_loading_counter += 1
|
|
88
|
+
# end
|
|
89
|
+
#
|
|
90
|
+
# def self.preload_css(css)
|
|
91
|
+
# @css_to_preload += "#{css}\n"
|
|
92
|
+
# end
|
|
93
|
+
#
|
|
94
|
+
# def self.has_observers?
|
|
95
|
+
# Hyperstack::Internal::State::Variable.observed?(self, :loaded_at)
|
|
96
|
+
# end
|
|
97
|
+
#
|
|
98
|
+
# class << self
|
|
99
|
+
# alias :observed? :has_observers?
|
|
100
|
+
# end
|
|
101
|
+
#
|
|
102
|
+
# prerender_footer do
|
|
103
|
+
# "<style>\n#{@css_to_preload}\n</style>".tap { @css_to_preload = ""}
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# if RUBY_ENGINE == 'opal'
|
|
107
|
+
#
|
|
108
|
+
# # +: I DONT THINK WE USE opal-jquery in this module anymore - require 'opal-jquery' if opal_client?
|
|
109
|
+
# # -: You think wrong. add_style_sheet uses the jQuery $, after_mount too, others too
|
|
110
|
+
# # -: I removed those references. Now you think right.
|
|
111
|
+
#
|
|
112
|
+
# include Hyperstack::Component
|
|
113
|
+
#
|
|
114
|
+
# param :render_original_child
|
|
115
|
+
# param :loading
|
|
116
|
+
#
|
|
117
|
+
# class << self
|
|
118
|
+
#
|
|
119
|
+
# def loading?
|
|
120
|
+
# @is_loading
|
|
121
|
+
# end
|
|
122
|
+
#
|
|
123
|
+
# def loading!
|
|
124
|
+
# Hyperstack::Internal::Component::RenderingContext.waiting_on_resources = true
|
|
125
|
+
# Hyperstack::Internal::State::Variable.get(self, :loaded_at)
|
|
126
|
+
# # this was moved to where the fetch is actually pushed on to the fetch array in isomorphic base
|
|
127
|
+
# # Hyperstack::Internal::State::Variable.set(self, :quiet, false)
|
|
128
|
+
# @is_loading = true
|
|
129
|
+
# end
|
|
130
|
+
#
|
|
131
|
+
# def loaded_at(loaded_at)
|
|
132
|
+
# Hyperstack::Internal::State::Variable.set(self, :loaded_at, loaded_at)
|
|
133
|
+
# @is_loading = false
|
|
134
|
+
# end
|
|
135
|
+
#
|
|
136
|
+
# def quiet?
|
|
137
|
+
# Hyperstack::Internal::State::Variable.get(self, :quiet)
|
|
138
|
+
# end
|
|
139
|
+
#
|
|
140
|
+
# def page_loaded?
|
|
141
|
+
# Hyperstack::Internal::State::Variable.get(self, :page_loaded)
|
|
142
|
+
# end
|
|
143
|
+
#
|
|
144
|
+
# def quiet!
|
|
145
|
+
# Hyperstack::Internal::State::Variable.set(self, :quiet, true)
|
|
146
|
+
# after(1) { Hyperstack::Internal::State::Variable.set(self, :page_loaded, true) } unless on_opal_server? or @page_loaded
|
|
147
|
+
# @page_loaded = true
|
|
148
|
+
# end
|
|
149
|
+
#
|
|
150
|
+
# def add_style_sheet
|
|
151
|
+
# # directly assigning the code to the variable triggers a opal 0.10.5 compiler bug.
|
|
152
|
+
# unless @style_sheet_added
|
|
153
|
+
# %x{
|
|
154
|
+
# var style_el = document.createElement("style");
|
|
155
|
+
# style_el.setAttribute("type", "text/css");
|
|
156
|
+
# style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none !important; }\n" +
|
|
157
|
+
# ".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none !important; }";
|
|
158
|
+
# document.head.append(style_el);
|
|
159
|
+
# }
|
|
160
|
+
# @style_sheet_added = true
|
|
161
|
+
# end
|
|
162
|
+
# end
|
|
163
|
+
#
|
|
164
|
+
# end
|
|
165
|
+
#
|
|
166
|
+
# def after_mount_and_update
|
|
167
|
+
# @waiting_on_resources = @Loading
|
|
168
|
+
# node = dom_node
|
|
169
|
+
# %x{
|
|
170
|
+
# Array.from(node.children).forEach(
|
|
171
|
+
# function(current_node, current_index, list_obj) {
|
|
172
|
+
# if (current_index > 0 && current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
|
|
173
|
+
# current_node.className = current_node.className + ' reactive_record_show_when_loaded';
|
|
174
|
+
# } else if (current_index == 0 && current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
|
|
175
|
+
# current_node.className = current_node.className + ' reactive_record_show_while_loading';
|
|
176
|
+
# }
|
|
177
|
+
# }
|
|
178
|
+
# );
|
|
179
|
+
# }
|
|
180
|
+
# nil
|
|
181
|
+
# end
|
|
182
|
+
#
|
|
183
|
+
# before_mount do
|
|
184
|
+
# @uniq_id = WhileLoading.get_next_while_loading_counter
|
|
185
|
+
# WhileLoading.preload_css(
|
|
186
|
+
# ":not(.reactive_record_is_loading).reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1) {\n"+
|
|
187
|
+
# " display: none;\n"+
|
|
188
|
+
# "}\n"
|
|
189
|
+
# )
|
|
190
|
+
# end
|
|
191
|
+
#
|
|
192
|
+
# after_mount do
|
|
193
|
+
# WhileLoading.add_style_sheet
|
|
194
|
+
# after_mount_and_update
|
|
195
|
+
# end
|
|
196
|
+
#
|
|
197
|
+
# after_update :after_mount_and_update
|
|
198
|
+
#
|
|
199
|
+
# render do
|
|
200
|
+
# @RenderOriginalChild.call(@uniq_id)
|
|
201
|
+
# end
|
|
202
|
+
#
|
|
203
|
+
# end
|
|
204
|
+
#
|
|
205
|
+
# end
|
|
206
|
+
#
|
|
207
|
+
# end
|
|
208
|
+
#
|
|
209
|
+
# module Hyperstack
|
|
210
|
+
# module Component
|
|
211
|
+
#
|
|
212
|
+
# class Element
|
|
213
|
+
#
|
|
214
|
+
# def while_loading(display = "", &loading_display_block)
|
|
215
|
+
# original_block = block || -> () {}
|
|
216
|
+
#
|
|
217
|
+
# if display.respond_to? :as_node
|
|
218
|
+
# display = display.as_node
|
|
219
|
+
# block = lambda { display.render; instance_eval(&original_block) }
|
|
220
|
+
# elsif !loading_display_block
|
|
221
|
+
# block = lambda { display; instance_eval(&original_block) }
|
|
222
|
+
# else
|
|
223
|
+
# block = ->() { instance_eval(&loading_display_block); instance_eval(&original_block) }
|
|
224
|
+
# end
|
|
225
|
+
# loading_child = Internal::Component::RenderingContext.build do |buffer|
|
|
226
|
+
# Hyperstack::Internal::Component::RenderingContext.render(:span, key: 1, &loading_display_block) #{ to_s }
|
|
227
|
+
# buffer.dup
|
|
228
|
+
# end
|
|
229
|
+
# children = `#{@native}.props.children.slice(0)`
|
|
230
|
+
# children.unshift(loading_child[0].instance_eval { @native })
|
|
231
|
+
# @native = `React.cloneElement(#{@native}, #{@properties.shallow_to_n}, #{children})`
|
|
232
|
+
# render_original_child = lambda do |uniq_id|
|
|
233
|
+
# classes = [
|
|
234
|
+
# @properties[:class], @properties[:className],
|
|
235
|
+
# "reactive_record_while_loading_container_#{uniq_id}"
|
|
236
|
+
# ].compact.join(' ')
|
|
237
|
+
# @properties.merge!({
|
|
238
|
+
# "data-reactive_record_while_loading_container_id" => uniq_id,
|
|
239
|
+
# "data-reactive_record_enclosing_while_loading_container_id" => uniq_id,
|
|
240
|
+
# className: classes
|
|
241
|
+
# })
|
|
242
|
+
# @native = `React.cloneElement(#{@native}, #{@properties.shallow_to_n})`
|
|
243
|
+
# render
|
|
244
|
+
# end
|
|
245
|
+
# delete
|
|
246
|
+
# ReactAPI.create_element(
|
|
247
|
+
# ReactiveRecord::WhileLoading,
|
|
248
|
+
# loading: waiting_on_resources,
|
|
249
|
+
# render_original_child: render_original_child)
|
|
250
|
+
# end
|
|
251
|
+
#
|
|
252
|
+
# def hide_while_loading
|
|
253
|
+
# while_loading
|
|
254
|
+
# end
|
|
255
|
+
#
|
|
256
|
+
# end
|
|
257
|
+
# end
|
|
258
|
+
# end
|
|
259
|
+
#
|
|
260
|
+
|
|
261
|
+
|
|
77
262
|
class WhileLoading
|
|
78
263
|
|
|
79
264
|
include Hyperstack::Component::IsomorphicHelpers
|
|
@@ -116,6 +301,7 @@ module ReactiveRecord
|
|
|
116
301
|
param :loading_children
|
|
117
302
|
param :element_type
|
|
118
303
|
param :element_props
|
|
304
|
+
others :other_props
|
|
119
305
|
param :display, default: ''
|
|
120
306
|
|
|
121
307
|
class << self
|
|
@@ -157,8 +343,8 @@ module ReactiveRecord
|
|
|
157
343
|
%x{
|
|
158
344
|
var style_el = document.createElement("style");
|
|
159
345
|
style_el.setAttribute("type", "text/css");
|
|
160
|
-
style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none; }\n" +
|
|
161
|
-
".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none; }";
|
|
346
|
+
style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none !important; }\n" +
|
|
347
|
+
".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none !important; }";
|
|
162
348
|
document.head.append(style_el);
|
|
163
349
|
}
|
|
164
350
|
@style_sheet_added = true
|
|
@@ -167,53 +353,57 @@ module ReactiveRecord
|
|
|
167
353
|
|
|
168
354
|
end
|
|
169
355
|
|
|
170
|
-
|
|
171
|
-
@uniq_id = WhileLoading.get_next_while_loading_counter
|
|
172
|
-
WhileLoading.preload_css(
|
|
173
|
-
".reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1n+#{@LoadedChildren.count+1}) {\n"+
|
|
174
|
-
" display: none;\n"+
|
|
175
|
-
"}\n"
|
|
176
|
-
)
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
after_mount do
|
|
356
|
+
def after_mount_and_update
|
|
180
357
|
@waiting_on_resources = @Loading
|
|
181
|
-
WhileLoading.add_style_sheet
|
|
182
358
|
node = dom_node
|
|
183
359
|
%x{
|
|
184
|
-
|
|
185
|
-
nodes.forEach(
|
|
360
|
+
Array.from(node.children).forEach(
|
|
186
361
|
function(current_node, current_index, list_obj) {
|
|
187
|
-
if (current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
|
|
362
|
+
if (current_index > 0 && current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
|
|
188
363
|
current_node.className = current_node.className + ' reactive_record_show_when_loaded';
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
);
|
|
192
|
-
nodes = node.querySelectorAll(':nth-child(1n+'+#{@LoadedChildren.count+1}+')');
|
|
193
|
-
nodes.forEach(
|
|
194
|
-
function(current_node, current_index, list_obj) {
|
|
195
|
-
if (current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
|
|
364
|
+
} else if (current_index == 0 && current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
|
|
196
365
|
current_node.className = current_node.className + ' reactive_record_show_while_loading';
|
|
197
366
|
}
|
|
198
367
|
}
|
|
199
368
|
);
|
|
200
369
|
}
|
|
370
|
+
nil
|
|
201
371
|
end
|
|
202
372
|
|
|
203
|
-
|
|
204
|
-
@
|
|
373
|
+
before_mount do
|
|
374
|
+
@uniq_id = WhileLoading.get_next_while_loading_counter
|
|
375
|
+
WhileLoading.preload_css(
|
|
376
|
+
":not(.reactive_record_is_loading).reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1) {\n"+
|
|
377
|
+
" display: none;\n"+
|
|
378
|
+
"}\n"
|
|
379
|
+
)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
after_mount do
|
|
383
|
+
WhileLoading.add_style_sheet
|
|
384
|
+
after_mount_and_update
|
|
205
385
|
end
|
|
206
386
|
|
|
387
|
+
after_update :after_mount_and_update
|
|
388
|
+
|
|
207
389
|
render do
|
|
390
|
+
# return ReactAPI.create_element(@ElementType[0], @ElementProps.dup) do
|
|
391
|
+
# @LoadedChildren
|
|
392
|
+
# end
|
|
208
393
|
props = @ElementProps.dup
|
|
209
|
-
classes = [
|
|
394
|
+
classes = [
|
|
395
|
+
props[:class], props[:className],
|
|
396
|
+
@OtherProps.delete(:class), @OtherProps.delete(:className),
|
|
397
|
+
"reactive_record_while_loading_container_#{@uniq_id}"
|
|
398
|
+
].compact.join(" ")
|
|
210
399
|
props.merge!({
|
|
211
400
|
"data-reactive_record_while_loading_container_id" => @uniq_id,
|
|
212
401
|
"data-reactive_record_enclosing_while_loading_container_id" => @uniq_id,
|
|
213
402
|
class: classes
|
|
214
403
|
})
|
|
404
|
+
props.merge!(@OtherProps)
|
|
215
405
|
ReactAPI.create_element(@ElementType[0], props) do
|
|
216
|
-
@
|
|
406
|
+
@LoadingChildren + @LoadedChildren
|
|
217
407
|
end.tap { |e| e.waiting_on_resources = @Loading }
|
|
218
408
|
end
|
|
219
409
|
|
|
@@ -231,6 +421,10 @@ module Hyperstack
|
|
|
231
421
|
def while_loading(display = "", &loading_display_block)
|
|
232
422
|
loaded_children = []
|
|
233
423
|
loaded_children = block.call.dup if block
|
|
424
|
+
if loaded_children.last.is_a? String
|
|
425
|
+
loaded_children <<
|
|
426
|
+
Hyperstack::Internal::Component::ReactWrapper.create_element(:span) { loaded_children.pop }
|
|
427
|
+
end
|
|
234
428
|
if display.respond_to? :as_node
|
|
235
429
|
display = display.as_node
|
|
236
430
|
loading_display_block = lambda { display.render }
|
|
@@ -238,12 +432,10 @@ module Hyperstack
|
|
|
238
432
|
loading_display_block = lambda { display }
|
|
239
433
|
end
|
|
240
434
|
loading_children = Internal::Component::RenderingContext.build do |buffer|
|
|
241
|
-
|
|
242
|
-
result = result.to_s if result.try :acts_as_string?
|
|
243
|
-
result.span.tap { |e| e.waiting_on_resources = Internal::Component::RenderingContext.waiting_on_resources } if result.is_a? String
|
|
435
|
+
Hyperstack::Internal::Component::RenderingContext.render(:span, &loading_display_block) #{ to_s }
|
|
244
436
|
buffer.dup
|
|
245
437
|
end
|
|
246
|
-
|
|
438
|
+
as_node
|
|
247
439
|
new_element = ReactAPI.create_element(
|
|
248
440
|
ReactiveRecord::WhileLoading,
|
|
249
441
|
loading: waiting_on_resources,
|
|
@@ -252,7 +444,7 @@ module Hyperstack
|
|
|
252
444
|
element_type: [type],
|
|
253
445
|
element_props: properties)
|
|
254
446
|
|
|
255
|
-
Internal::Component::RenderingContext.replace(self, new_element)
|
|
447
|
+
#Internal::Component::RenderingContext.replace(self, new_element)
|
|
256
448
|
end
|
|
257
449
|
|
|
258
450
|
def hide_while_loading
|
|
@@ -267,6 +459,10 @@ if RUBY_ENGINE == 'opal'
|
|
|
267
459
|
module Hyperstack
|
|
268
460
|
module Component
|
|
269
461
|
|
|
462
|
+
def quiet?
|
|
463
|
+
Hyperstack::Internal::State::Variable.get(ReactiveRecord::WhileLoading, :quiet)
|
|
464
|
+
end
|
|
465
|
+
|
|
270
466
|
alias_method :original_component_did_mount, :component_did_mount
|
|
271
467
|
|
|
272
468
|
def component_did_mount(*args)
|
|
@@ -2,9 +2,12 @@ module ReactiveRecord
|
|
|
2
2
|
class Broadcast
|
|
3
3
|
|
|
4
4
|
def self.after_commit(operation, model)
|
|
5
|
+
# Calling public_columns_hash once insures all policies are loaded
|
|
6
|
+
# before the first broadcast.
|
|
7
|
+
@public_columns_hash ||= ActiveRecord::Base.public_columns_hash
|
|
5
8
|
Hyperstack::InternalPolicy.regulate_broadcast(model) do |data|
|
|
6
9
|
if !Hyperstack.on_server? && Hyperstack::Connection.root_path
|
|
7
|
-
send_to_server(operation, data) rescue nil # server no longer running so ignore
|
|
10
|
+
send_to_server(operation, data) rescue nil # fails if server no longer running so ignore
|
|
8
11
|
else
|
|
9
12
|
SendPacket.run(data, operation: operation)
|
|
10
13
|
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].foreign_key == model.id
|
|
93
|
+
self.class.reflections[attr_name.to_s].foreign_key == model.id
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -103,7 +103,19 @@ class ActiveRecord::Base
|
|
|
103
103
|
self.acting_user = old
|
|
104
104
|
self
|
|
105
105
|
else
|
|
106
|
-
|
|
106
|
+
acting_user_string =
|
|
107
|
+
if acting_user
|
|
108
|
+
id = user.respond_to?(:id) ? user.id : user
|
|
109
|
+
"not allowed for acting_user: <##{user.class} id: #{user}>"
|
|
110
|
+
else
|
|
111
|
+
"not allowed without acting_user (acting_user = nil)"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
message = "CRUD access violation: <##{self.class} id: #{self.id}> - #{permission}(#{args}) #{acting_user_string}"
|
|
115
|
+
if permission == :view_permitted?
|
|
116
|
+
details = Hyperstack::PolicyDiagnostics.policy_dump_for(self, user)
|
|
117
|
+
end
|
|
118
|
+
Hyperstack::InternalPolicy.raise_operation_access_violation(message, details || '')
|
|
107
119
|
end
|
|
108
120
|
end
|
|
109
121
|
|
|
@@ -229,6 +229,26 @@ module ReactiveRecord
|
|
|
229
229
|
@db_cache.add_item_to_cache self
|
|
230
230
|
end
|
|
231
231
|
|
|
232
|
+
def to_s
|
|
233
|
+
acting_user_string =
|
|
234
|
+
if acting_user
|
|
235
|
+
" - with acting user: <#{acting_user.class.name} id: #{acting_user.id}>"
|
|
236
|
+
else
|
|
237
|
+
' - with no acting user'
|
|
238
|
+
end
|
|
239
|
+
vector.collect do |e|
|
|
240
|
+
if e.is_a? String
|
|
241
|
+
e
|
|
242
|
+
elsif e.is_a? Array
|
|
243
|
+
e.length > 1 ? "#{e.first}(#{e[1..-1].join(', ')})" : e.first
|
|
244
|
+
else
|
|
245
|
+
e.name
|
|
246
|
+
end
|
|
247
|
+
end.join('.') + acting_user_string
|
|
248
|
+
rescue
|
|
249
|
+
vector.to_s + acting_user_string
|
|
250
|
+
end
|
|
251
|
+
|
|
232
252
|
def start_timing(&block)
|
|
233
253
|
ServerDataCache.class.start_timing(&block)
|
|
234
254
|
end
|
|
@@ -245,11 +265,11 @@ module ReactiveRecord
|
|
|
245
265
|
cache_item.apply_star || representative
|
|
246
266
|
elsif method == "*all"
|
|
247
267
|
# if we secure the collection then we assume its okay to read the ids
|
|
248
|
-
secured_value = cache_item.value.__secure_collection_check(
|
|
268
|
+
secured_value = cache_item.value.__secure_collection_check(cache_item)
|
|
249
269
|
cache_item.build_new_cache_item(timing(:active_record) { secured_value.collect { |record| record.id } }, method, method)
|
|
250
270
|
elsif method == "*count"
|
|
251
|
-
secured_value = cache_item.value.__secure_collection_check(
|
|
252
|
-
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.__secure_collection_check(
|
|
271
|
+
secured_value = cache_item.value.__secure_collection_check(cache_item)
|
|
272
|
+
cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.__secure_collection_check(cache_item).count }, method, method)
|
|
253
273
|
elsif preloaded_value = @preloaded_records[cache_item.absolute_vector + [method]]
|
|
254
274
|
# no security check needed since we already evaluated this
|
|
255
275
|
cache_item.build_new_cache_item(preloaded_value, method, method)
|
|
@@ -273,10 +293,10 @@ module ReactiveRecord
|
|
|
273
293
|
else
|
|
274
294
|
raise "method missing"
|
|
275
295
|
end
|
|
276
|
-
rescue Exception => e # this check may no longer be needed as we are quite explicit now on which methods we apply
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
|
280
300
|
end
|
|
281
301
|
end
|
|
282
302
|
end
|
|
@@ -296,7 +316,7 @@ module ReactiveRecord
|
|
|
296
316
|
end
|
|
297
317
|
|
|
298
318
|
def apply_star
|
|
299
|
-
if @value && @value.__secure_collection_check(
|
|
319
|
+
if @value && @value.__secure_collection_check(self) && @value.length > 0
|
|
300
320
|
i = -1
|
|
301
321
|
@value.inject(nil) do |representative, current_value|
|
|
302
322
|
i += 1
|
data/spec_fails.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
rspec ./spec/batch5/save_while_loading_spec.rb:28 # save while loading with push
|
|
2
|
+
rspec ./spec/batch4/default_value_spec.rb:40 # defaultValue special handling will not use the defaultValue param until data is loaded - unit test
|
|
3
|
+
rspec ./spec/batch3/revert_spec.rb:39 # reverting records adds the todo to adam's todos and expects adam to change
|
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.3
|
|
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: 2019-01-17 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activemodel
|
|
@@ -45,42 +45,48 @@ dependencies:
|
|
|
45
45
|
requirements:
|
|
46
46
|
- - '='
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: 1.0.alpha1.
|
|
48
|
+
version: 1.0.alpha1.3
|
|
49
49
|
type: :runtime
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
53
|
- - '='
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: 1.0.alpha1.
|
|
55
|
+
version: 1.0.alpha1.3
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: hyper-operation
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
60
|
- - '='
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 1.0.alpha1.
|
|
62
|
+
version: 1.0.alpha1.3
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
67
|
- - '='
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 1.0.alpha1.
|
|
69
|
+
version: 1.0.alpha1.3
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: bundler
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
|
74
74
|
- - ">="
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
|
-
version:
|
|
76
|
+
version: 1.17.3
|
|
77
|
+
- - "<"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '2.1'
|
|
77
80
|
type: :development
|
|
78
81
|
prerelease: false
|
|
79
82
|
version_requirements: !ruby/object:Gem::Requirement
|
|
80
83
|
requirements:
|
|
81
84
|
- - ">="
|
|
82
85
|
- !ruby/object:Gem::Version
|
|
83
|
-
version:
|
|
86
|
+
version: 1.17.3
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '2.1'
|
|
84
90
|
- !ruby/object:Gem::Dependency
|
|
85
91
|
name: capybara
|
|
86
92
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -113,30 +119,30 @@ dependencies:
|
|
|
113
119
|
name: libv8
|
|
114
120
|
requirement: !ruby/object:Gem::Requirement
|
|
115
121
|
requirements:
|
|
116
|
-
- - "
|
|
122
|
+
- - ">="
|
|
117
123
|
- !ruby/object:Gem::Version
|
|
118
|
-
version:
|
|
124
|
+
version: '0'
|
|
119
125
|
type: :development
|
|
120
126
|
prerelease: false
|
|
121
127
|
version_requirements: !ruby/object:Gem::Requirement
|
|
122
128
|
requirements:
|
|
123
|
-
- - "
|
|
129
|
+
- - ">="
|
|
124
130
|
- !ruby/object:Gem::Version
|
|
125
|
-
version:
|
|
131
|
+
version: '0'
|
|
126
132
|
- !ruby/object:Gem::Dependency
|
|
127
133
|
name: mini_racer
|
|
128
134
|
requirement: !ruby/object:Gem::Requirement
|
|
129
135
|
requirements:
|
|
130
136
|
- - "~>"
|
|
131
137
|
- !ruby/object:Gem::Version
|
|
132
|
-
version: 0.
|
|
138
|
+
version: 0.2.4
|
|
133
139
|
type: :development
|
|
134
140
|
prerelease: false
|
|
135
141
|
version_requirements: !ruby/object:Gem::Requirement
|
|
136
142
|
requirements:
|
|
137
143
|
- - "~>"
|
|
138
144
|
- !ruby/object:Gem::Version
|
|
139
|
-
version: 0.
|
|
145
|
+
version: 0.2.4
|
|
140
146
|
- !ruby/object:Gem::Dependency
|
|
141
147
|
name: selenium-webdriver
|
|
142
148
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -642,6 +648,7 @@ files:
|
|
|
642
648
|
- lib/reactive_record/scope_description.rb
|
|
643
649
|
- lib/reactive_record/serializers.rb
|
|
644
650
|
- lib/reactive_record/server_data_cache.rb
|
|
651
|
+
- spec_fails.txt
|
|
645
652
|
homepage: http://ruby-hyperstack.org
|
|
646
653
|
licenses:
|
|
647
654
|
- MIT
|
|
@@ -661,8 +668,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
661
668
|
- !ruby/object:Gem::Version
|
|
662
669
|
version: 1.3.1
|
|
663
670
|
requirements: []
|
|
664
|
-
|
|
665
|
-
rubygems_version: 2.7.8
|
|
671
|
+
rubygems_version: 3.0.2
|
|
666
672
|
signing_key:
|
|
667
673
|
specification_version: 4
|
|
668
674
|
summary: React based CRUD access and Synchronization of active record models across
|