hyper-mesh 1.0.0.lap27 → 1.0.0.lap28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +6 -2
- data/Gemfile +0 -1
- data/Rakefile +2 -2
- data/hyper-mesh.gemspec +1 -1
- data/lib/active_record_base.rb +39 -27
- data/lib/hyper-mesh.rb +6 -1
- data/lib/hypermesh/version.rb +1 -1
- data/lib/object/tap.rb +7 -0
- data/lib/reactive_record/active_record/associations.rb +14 -3
- data/lib/reactive_record/active_record/base.rb +1 -2
- data/lib/reactive_record/active_record/class_methods.rb +120 -67
- data/lib/reactive_record/active_record/error.rb +17 -12
- data/lib/reactive_record/active_record/errors.rb +374 -0
- data/lib/reactive_record/active_record/instance_methods.rb +58 -67
- data/lib/reactive_record/active_record/reactive_record/backing_record_inspector.rb +1 -4
- data/lib/reactive_record/active_record/reactive_record/base.rb +129 -234
- data/lib/reactive_record/active_record/reactive_record/collection.rb +51 -18
- data/lib/reactive_record/active_record/reactive_record/column_types.rb +5 -3
- data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +6 -4
- data/lib/reactive_record/active_record/reactive_record/getters.rb +133 -0
- data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +99 -87
- data/lib/reactive_record/active_record/reactive_record/lookup_tables.rb +54 -0
- data/lib/reactive_record/active_record/reactive_record/operations.rb +2 -1
- data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +1 -1
- data/lib/reactive_record/active_record/reactive_record/setters.rb +194 -0
- data/lib/reactive_record/active_record/reactive_record/while_loading.rb +4 -5
- data/lib/reactive_record/active_record_error.rb +4 -0
- data/lib/reactive_record/broadcast.rb +55 -18
- data/lib/reactive_record/permissions.rb +5 -4
- data/lib/reactive_record/scope_description.rb +14 -6
- data/lib/reactive_record/server_data_cache.rb +119 -70
- metadata +16 -13
- data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +0 -189
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 496e78b04675fc8421cf1bf977361c6a6049769a8fd2d2dd9c0f0766735a41d5
|
4
|
+
data.tar.gz: 55513ce6b73c89665be0dddc74843cc59df11079233569ea404302eb10eddd1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0a0152a43aaeb0e3ecadc152db2e71a3a0fe24e4775ead3f95276c5d4d8351b53d8ef2e766309bdb36b574273b3ae0bb845b2d2d38ba2363dcda2a59892ace3
|
7
|
+
data.tar.gz: 3316b9c3a125034a8bbed27a5263412f863b160dd7246eec08bddba0f081623fb11df34c3e51b52f2fce8faae522335171c988905e5fc54635210b7846cb7cd1
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
+
|
1
2
|
Metrics/LineLength:
|
2
3
|
Max: 100
|
3
4
|
|
4
5
|
Style/MutableConstant:
|
5
6
|
Enabled: false
|
6
7
|
|
7
|
-
Lint/LiteralInCondition:
|
8
|
-
|
8
|
+
# Lint/LiteralInCondition:
|
9
|
+
# Enabled: false
|
9
10
|
|
10
11
|
Style/CommandLiteral:
|
11
12
|
EnforcedStyle: mixed
|
13
|
+
|
14
|
+
AllCops:
|
15
|
+
TargetRubyVersion: 2.4.1
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require "rspec/core/rake_task"
|
|
4
4
|
|
5
5
|
|
6
6
|
task :spec do
|
7
|
-
(1..
|
7
|
+
(1..7).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
|
8
8
|
end
|
9
9
|
|
10
10
|
namespace :spec do
|
@@ -12,7 +12,7 @@ namespace :spec do
|
|
12
12
|
sh %{bundle update}
|
13
13
|
sh %{cd spec/test_app; bundle update; bundle exec rails db:setup} # may need ;bundle exec rails db:setup as well
|
14
14
|
end
|
15
|
-
(1..
|
15
|
+
(1..7).each do |batch|
|
16
16
|
RSpec::Core::RakeTask.new(:"batch#{batch}") do |t|
|
17
17
|
t.pattern = "spec/batch#{batch}/**/*_spec.rb"
|
18
18
|
end
|
data/hyper-mesh.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
# }
|
22
22
|
|
23
23
|
spec.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(examples|gemfiles|pkg|reactive_record_test_app|spec)/}) }
|
24
|
-
spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
24
|
+
# spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
25
25
|
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
26
26
|
spec.require_paths = ['lib']
|
27
27
|
|
data/lib/active_record_base.rb
CHANGED
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
41
41
|
attr_accessor :acting_user
|
42
42
|
def __secure_collection_check(acting_user)
|
43
43
|
return self if __synchromesh_permission_granted
|
44
|
-
return self if __secure_remote_access_to_unscoped(acting_user).__synchromesh_permission_granted
|
44
|
+
return self if __secure_remote_access_to_unscoped(self, acting_user).__synchromesh_permission_granted
|
45
45
|
denied!
|
46
46
|
end
|
47
47
|
end
|
@@ -62,11 +62,11 @@ module ActiveRecord
|
|
62
62
|
# Here we set up the base `all` and `unscoped` methods. See below for more on how
|
63
63
|
# access protection works on relationships.
|
64
64
|
|
65
|
-
def __secure_remote_access_to_all(_acting_user)
|
65
|
+
def __secure_remote_access_to_all(_self, _acting_user)
|
66
66
|
all
|
67
67
|
end
|
68
68
|
|
69
|
-
def __secure_remote_access_to_unscoped(_acting_user, *args)
|
69
|
+
def __secure_remote_access_to_unscoped(_self, _acting_user, *args)
|
70
70
|
unscoped(*args)
|
71
71
|
end
|
72
72
|
|
@@ -77,8 +77,8 @@ module ActiveRecord
|
|
77
77
|
# For finder_method we have to preapply `all` so that we always have a relationship
|
78
78
|
|
79
79
|
def finder_method(name, &block)
|
80
|
-
singleton_class.send(:define_method, :"__secure_remote_access_to__#{name}") do |acting_user, *args|
|
81
|
-
this = respond_to?(:acting_user) ?
|
80
|
+
singleton_class.send(:define_method, :"__secure_remote_access_to__#{name}") do |this, acting_user, *args|
|
81
|
+
this = respond_to?(:acting_user) ? this : all
|
82
82
|
begin
|
83
83
|
old = this.acting_user
|
84
84
|
this.acting_user = acting_user
|
@@ -98,7 +98,7 @@ module ActiveRecord
|
|
98
98
|
# callable from the server internally
|
99
99
|
define_method(name, &block)
|
100
100
|
# callable remotely from the client
|
101
|
-
define_method("__secure_remote_access_to_#{name}") do |acting_user, *args|
|
101
|
+
define_method("__secure_remote_access_to_#{name}") do |_self, acting_user, *args|
|
102
102
|
begin
|
103
103
|
old = self.acting_user
|
104
104
|
self.acting_user = acting_user
|
@@ -166,17 +166,17 @@ module ActiveRecord
|
|
166
166
|
end
|
167
167
|
|
168
168
|
# helper method to set the value of __synchromesh_permission_granted on the relationship
|
169
|
-
#
|
170
|
-
#
|
169
|
+
# Set acting_user on the object, then or in the result of running the block in context
|
170
|
+
# of the obj with the current value of __synchromesh_permission_granted
|
171
171
|
|
172
|
-
def __set_synchromesh_permission_granted(
|
173
|
-
|
174
|
-
old = acting_user
|
172
|
+
def __set_synchromesh_permission_granted(old_rel, new_rel, obj, acting_user, args = [], &block)
|
173
|
+
saved_acting_user = obj.acting_user
|
175
174
|
obj.acting_user = acting_user
|
176
|
-
|
177
|
-
|
175
|
+
new_rel.__synchromesh_permission_granted =
|
176
|
+
obj.instance_exec(*args, &block) || (old_rel && old_rel.try(:__synchromesh_permission_granted))
|
177
|
+
new_rel
|
178
178
|
ensure
|
179
|
-
obj.acting_user =
|
179
|
+
obj.acting_user = saved_acting_user
|
180
180
|
end
|
181
181
|
|
182
182
|
# regulate scope has to deal with the special case that the scope returns an
|
@@ -184,16 +184,17 @@ module ActiveRecord
|
|
184
184
|
|
185
185
|
def regulate_scope(name, &block)
|
186
186
|
name, block = __synchromesh_parse_regulator_params(name, block)
|
187
|
-
singleton_class.send(:define_method, :"__secure_remote_access_to_#{name}") do |acting_user, *args|
|
188
|
-
r = send(name, *args)
|
187
|
+
singleton_class.send(:define_method, :"__secure_remote_access_to_#{name}") do |this, acting_user, *args|
|
188
|
+
r = this.send(name, *args)
|
189
189
|
r = ReactiveRecordPsuedoRelationArray.new(r) if r.is_a? Array
|
190
|
-
__set_synchromesh_permission_granted(r, r, acting_user, args, &block)
|
190
|
+
__set_synchromesh_permission_granted(this, r, r, acting_user, args, &block)
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
194
194
|
# regulate_default_scope
|
195
195
|
|
196
|
-
def regulate_default_scope(&block)
|
196
|
+
def regulate_default_scope(*args, &block)
|
197
|
+
block = __synchromesh_parse_regulator_params({ all: args[0] }, block).last unless args.empty?
|
197
198
|
regulate_scope(:all, &block)
|
198
199
|
end
|
199
200
|
|
@@ -229,9 +230,9 @@ module ActiveRecord
|
|
229
230
|
|
230
231
|
def regulate_relationship(name, &block)
|
231
232
|
name, block = __synchromesh_parse_regulator_params(name, block)
|
232
|
-
define_method(:"__secure_remote_access_to_#{name}") do |acting_user, *args|
|
233
|
-
|
234
|
-
send(name, *args),
|
233
|
+
define_method(:"__secure_remote_access_to_#{name}") do |this, acting_user, *args|
|
234
|
+
this.class.__set_synchromesh_permission_granted(
|
235
|
+
nil, this.send(name, *args), this, acting_user, &block
|
235
236
|
)
|
236
237
|
end
|
237
238
|
end
|
@@ -254,21 +255,21 @@ module ActiveRecord
|
|
254
255
|
# simply return `find(1)` but if you try returning `find(1).name` the permission system
|
255
256
|
# will check to see if the name attribute can be legally sent to the current acting user.
|
256
257
|
|
257
|
-
def __secure_remote_access_to_find(_acting_user, *args)
|
258
|
+
def __secure_remote_access_to_find(_self, _acting_user, *args)
|
258
259
|
find(*args)
|
259
260
|
end
|
260
261
|
|
261
|
-
def __secure_remote_access_to_find_by(_acting_user, *args)
|
262
|
+
def __secure_remote_access_to_find_by(_self, _acting_user, *args)
|
262
263
|
find_by(*args)
|
263
264
|
end
|
264
265
|
|
265
266
|
%i[belongs_to has_one].each do |macro|
|
266
267
|
alias_method :"pre_syncromesh_#{macro}", macro
|
267
|
-
define_method(macro) do |name,
|
268
|
-
define_method(:"__secure_remote_access_to_#{name}") do |_acting_user, *args|
|
269
|
-
send(name, *args)
|
268
|
+
define_method(macro) do |name, *aargs, &block|
|
269
|
+
define_method(:"__secure_remote_access_to_#{name}") do |this, _acting_user, *args|
|
270
|
+
this.send(name, *args)
|
270
271
|
end
|
271
|
-
send(:"pre_syncromesh_#{macro}", name,
|
272
|
+
send(:"pre_syncromesh_#{macro}", name, *aargs, &block)
|
272
273
|
end
|
273
274
|
end
|
274
275
|
end
|
@@ -311,6 +312,17 @@ module ActiveRecord
|
|
311
312
|
return if do_not_synchronize?
|
312
313
|
ReactiveRecord::Broadcast.after_commit :destroy, self
|
313
314
|
end
|
315
|
+
|
316
|
+
def __hyperloop_secure_attributes(acting_user)
|
317
|
+
accessible_attributes =
|
318
|
+
Hyperloop::InternalPolicy.accessible_attributes_for(self, acting_user)
|
319
|
+
attributes.select { |attr| accessible_attributes.include? attr.to_sym }
|
320
|
+
end
|
321
|
+
|
322
|
+
# regulate built in scopes so they are accesible from the client
|
323
|
+
%i[limit offset].each do |scope|
|
324
|
+
regulate_scope(scope) {}
|
325
|
+
end
|
314
326
|
end
|
315
327
|
end
|
316
328
|
|
data/lib/hyper-mesh.rb
CHANGED
@@ -7,6 +7,9 @@ if RUBY_ENGINE == 'opal'
|
|
7
7
|
require 'time'
|
8
8
|
require 'date'
|
9
9
|
require 'kernel/itself' unless Object.instance_methods.include?(:itself)
|
10
|
+
require 'object/tap'
|
11
|
+
require "reactive_record/active_record_error"
|
12
|
+
require "reactive_record/active_record/errors"
|
10
13
|
require "reactive_record/active_record/error"
|
11
14
|
require "reactive_record/server_data_cache"
|
12
15
|
require "reactive_record/active_record/reactive_record/while_loading"
|
@@ -18,8 +21,10 @@ if RUBY_ENGINE == 'opal'
|
|
18
21
|
require "reactive_record/active_record/aggregations"
|
19
22
|
require "reactive_record/active_record/associations"
|
20
23
|
require "reactive_record/active_record/reactive_record/backing_record_inspector"
|
24
|
+
require "reactive_record/active_record/reactive_record/getters"
|
25
|
+
require "reactive_record/active_record/reactive_record/setters"
|
26
|
+
require "reactive_record/active_record/reactive_record/lookup_tables"
|
21
27
|
require "reactive_record/active_record/reactive_record/base"
|
22
|
-
require "reactive_record/active_record/reactive_record/reactive_set_relationship_helpers"
|
23
28
|
require "reactive_record/active_record/reactive_record/collection"
|
24
29
|
require "reactive_record/active_record/reactive_record/scoped_collection"
|
25
30
|
require "reactive_record/active_record/reactive_record/unscoped_collection"
|
data/lib/hypermesh/version.rb
CHANGED
data/lib/object/tap.rb
ADDED
@@ -6,13 +6,24 @@ module ActiveRecord
|
|
6
6
|
base_class.instance_eval { @associations ||= superclass.instance_eval { (@associations && @associations.dup) || [] } }
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.reflect_on_association(
|
10
|
-
|
9
|
+
def self.reflect_on_association(attr)
|
10
|
+
reflection_finder { |assoc| assoc.attribute == attr }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.reflect_on_association_by_foreign_key(key)
|
14
|
+
reflection_finder { |assoc| assoc.association_foreign_key == key }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.reflection_finder(&block)
|
18
|
+
found = reflect_on_all_associations.detect do |assoc|
|
19
|
+
assoc.owner_class == self && yield(assoc)
|
20
|
+
end
|
21
|
+
if found
|
11
22
|
found
|
12
23
|
elsif superclass == Base
|
13
24
|
nil
|
14
25
|
else
|
15
|
-
superclass.
|
26
|
+
superclass.reflection_finder(&block)
|
16
27
|
end
|
17
28
|
end
|
18
29
|
|
@@ -2,10 +2,15 @@ module ActiveRecord
|
|
2
2
|
|
3
3
|
module ClassMethods
|
4
4
|
|
5
|
-
|
5
|
+
alias _new_without_sti_type_cast new
|
6
|
+
|
7
|
+
def new(*args, &block)
|
8
|
+
_new_without_sti_type_cast(*args, &block).cast_to_current_sti_type
|
9
|
+
end
|
6
10
|
|
11
|
+
def base_class
|
7
12
|
unless self < Base
|
8
|
-
raise ActiveRecordError, "#{name} doesn't
|
13
|
+
raise ActiveRecordError, "#{name} doesn't descend from ActiveRecord"
|
9
14
|
end
|
10
15
|
|
11
16
|
if superclass == Base || superclass.abstract_class?
|
@@ -13,7 +18,6 @@ module ActiveRecord
|
|
13
18
|
else
|
14
19
|
superclass.base_class
|
15
20
|
end
|
16
|
-
|
17
21
|
end
|
18
22
|
|
19
23
|
def abstract_class?
|
@@ -21,19 +25,26 @@ module ActiveRecord
|
|
21
25
|
end
|
22
26
|
|
23
27
|
def primary_key
|
24
|
-
|
28
|
+
@primary_key_value ||= (self == base_class) ? :id : base_class.primary_key
|
25
29
|
end
|
26
30
|
|
27
31
|
def primary_key=(val)
|
28
|
-
|
32
|
+
@primary_key_value = val.to_s
|
29
33
|
end
|
30
34
|
|
31
35
|
def inheritance_column
|
32
|
-
|
36
|
+
return nil if @no_inheritance_column
|
37
|
+
@inheritance_column_value ||=
|
38
|
+
if self == base_class
|
39
|
+
@inheritance_column_value || 'type'
|
40
|
+
else
|
41
|
+
superclass.inheritance_column.tap { |v| @no_inheritance_column = !v }
|
42
|
+
end
|
33
43
|
end
|
34
44
|
|
35
45
|
def inheritance_column=(name)
|
36
|
-
|
46
|
+
@no_inheritance_column = !name
|
47
|
+
@inheritance_column_value = name
|
37
48
|
end
|
38
49
|
|
39
50
|
def model_name
|
@@ -42,11 +53,13 @@ module ActiveRecord
|
|
42
53
|
end
|
43
54
|
|
44
55
|
def find(id)
|
45
|
-
|
56
|
+
ReactiveRecord::Base.find(self, primary_key => id)
|
46
57
|
end
|
47
58
|
|
48
59
|
def find_by(opts = {})
|
49
|
-
|
60
|
+
dealiased_opts = {}
|
61
|
+
opts.each { |attr, value| dealiased_opts[_dealias_attribute(attr)] = value }
|
62
|
+
ReactiveRecord::Base.find(self, dealiased_opts)
|
50
63
|
end
|
51
64
|
|
52
65
|
def enum(*args)
|
@@ -57,6 +70,25 @@ module ActiveRecord
|
|
57
70
|
ReactiveRecord::Base.serialized?[self][attr] = true
|
58
71
|
end
|
59
72
|
|
73
|
+
def _dealias_attribute(new)
|
74
|
+
if self == base_class
|
75
|
+
_attribute_aliases[new] || new
|
76
|
+
else
|
77
|
+
_attribute_aliases[new] ||= superclass._dealias_attribute(new)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def _attribute_aliases
|
82
|
+
@_attribute_aliases ||= {}
|
83
|
+
end
|
84
|
+
|
85
|
+
def alias_attribute(new_name, old_name)
|
86
|
+
['', '=', '_changed?'].each do |variant|
|
87
|
+
define_method("#{new_name}#{variant}") { |*args, &block| send("#{old_name}#{variant}", *args, &block) }
|
88
|
+
end
|
89
|
+
_attribute_aliases[new_name] = old_name
|
90
|
+
end
|
91
|
+
|
60
92
|
# ignore any of these methods if they get called on the client. This list should be trimmed down to include only
|
61
93
|
# methods to be called as "macros" such as :after_create, etc...
|
62
94
|
SERVER_METHODS = [
|
@@ -145,7 +177,7 @@ module ActiveRecord
|
|
145
177
|
|
146
178
|
def method_missing(name, *args, &block)
|
147
179
|
if args.count == 1 && name.start_with?("find_by_") && !block
|
148
|
-
find_by(name.sub(/^find_by_/, "") => args[0])
|
180
|
+
find_by(_dealias_attribute(name.sub(/^find_by_/, "")) => args[0])
|
149
181
|
elsif [].respond_to?(name)
|
150
182
|
all.send(name, *args, &block)
|
151
183
|
elsif name.end_with?('!')
|
@@ -199,12 +231,25 @@ module ActiveRecord
|
|
199
231
|
root = ReactiveRecord::Collection
|
200
232
|
.new(self, nil, nil, self, 'all')
|
201
233
|
.extend(ReactiveRecord::UnscopedCollection)
|
202
|
-
(@_default_scopes || [{ client:
|
234
|
+
(@_default_scopes || [{ client: _all_filter }]).inject(root) do |scope, opts|
|
203
235
|
scope.build_child_scope(ReactiveRecord::ScopeDescription.new(self, :all, opts))
|
204
236
|
end
|
205
237
|
end
|
206
238
|
end
|
207
239
|
|
240
|
+
def _all_filter
|
241
|
+
# provides a filter for the all scopes taking into account STI subclasses
|
242
|
+
# note: within the lambda `self` will be the model instance
|
243
|
+
defining_class_is_base_class = base_class == self
|
244
|
+
defining_model_name = model_name
|
245
|
+
lambda do
|
246
|
+
# have to delay computation of inheritance column since it might
|
247
|
+
# not be defined when class is first defined
|
248
|
+
ic = self.class.inheritance_column
|
249
|
+
defining_class_is_base_class || !ic || self[ic] == defining_model_name
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
208
253
|
# def all=(_collection)
|
209
254
|
# raise "NO LONGER IMPLEMENTED DOESNT PLAY WELL WITH SYNCHROMESH"
|
210
255
|
# end
|
@@ -250,20 +295,27 @@ module ActiveRecord
|
|
250
295
|
[:belongs_to, :has_many, :has_one].each do |macro|
|
251
296
|
define_method(macro) do |*args| # is this a bug in opal? saying name, scope=nil, opts={} does not work!
|
252
297
|
name = args.first
|
253
|
-
define_method(name) { @backing_record.reactive_get!(name, nil) }
|
254
|
-
define_method("#{name}=") do |val|
|
255
|
-
@backing_record.reactive_set!(name, backing_record.convert(name, val).itself)
|
256
|
-
end
|
257
298
|
opts = (args.count > 1 and args.last.is_a? Hash) ? args.last : {}
|
258
|
-
Associations::AssociationReflection.new(self, macro, name, opts)
|
299
|
+
assoc = Associations::AssociationReflection.new(self, macro, name, opts)
|
300
|
+
if macro == :has_many
|
301
|
+
define_method(name) { @backing_record.get_has_many(assoc, nil) }
|
302
|
+
define_method("#{name}=") { |val| @backing_record.set_has_many(assoc, val) }
|
303
|
+
else
|
304
|
+
define_method(name) { @backing_record.get_belongs_to(assoc, nil) }
|
305
|
+
define_method("#{name}=") { |val| @backing_record.set_belongs_to(assoc, val) }
|
306
|
+
end
|
307
|
+
assoc
|
259
308
|
end
|
260
309
|
end
|
261
310
|
|
262
311
|
def composed_of(name, opts = {})
|
263
|
-
Aggregations::AggregationReflection.new(base_class, :composed_of, name, opts)
|
264
|
-
|
265
|
-
|
266
|
-
|
312
|
+
reflection = Aggregations::AggregationReflection.new(base_class, :composed_of, name, opts)
|
313
|
+
if reflection.klass < ActiveRecord::Base
|
314
|
+
define_method(name) { @backing_record.get_ar_aggregate(reflection, nil) }
|
315
|
+
define_method("#{name}=") { |val| @backing_record.set_ar_aggregate(reflection, val) }
|
316
|
+
else
|
317
|
+
define_method(name) { @backing_record.get_non_ar_aggregate(name, nil) }
|
318
|
+
define_method("#{name}=") { |val| @backing_record.set_non_ar_aggregate(reflection, val) }
|
267
319
|
end
|
268
320
|
end
|
269
321
|
|
@@ -282,73 +334,74 @@ module ActiveRecord
|
|
282
334
|
def server_method(name, default: nil)
|
283
335
|
server_methods[name] = { default: default }
|
284
336
|
define_method(name) do |*args|
|
285
|
-
vector = args.count.zero? ? name : [[name]+args]
|
286
|
-
@backing_record.
|
337
|
+
vector = args.count.zero? ? name : [[name] + args]
|
338
|
+
@backing_record.get_server_method(vector, nil)
|
287
339
|
end
|
288
340
|
define_method("#{name}!") do |*args|
|
289
|
-
vector = args.count.zero? ? name : [[name]+args]
|
290
|
-
@backing_record.
|
341
|
+
vector = args.count.zero? ? name : [[name] + args]
|
342
|
+
@backing_record.get_server_method(vector, true)
|
291
343
|
end
|
292
344
|
end
|
293
345
|
|
294
346
|
def define_attribute_methods
|
295
|
-
columns_hash.
|
296
|
-
next if name ==
|
297
|
-
define_method(name) { @backing_record.
|
298
|
-
define_method("#{name}!") { @backing_record.
|
299
|
-
define_method("#{name}=")
|
300
|
-
@backing_record.reactive_set!(name, backing_record.convert(name, val))
|
301
|
-
end
|
347
|
+
columns_hash.each do |name, column_hash|
|
348
|
+
next if name == primary_key
|
349
|
+
define_method(name) { @backing_record.get_attr_value(name, nil) }
|
350
|
+
define_method("#{name}!") { @backing_record.get_attr_value(name, true) }
|
351
|
+
define_method("#{name}=") { |val| @backing_record.set_attr_value(name, val) }
|
302
352
|
define_method("#{name}_changed?") { @backing_record.changed?(name) }
|
353
|
+
define_method("#{name}?") { @backing_record.get_attr_value(name, nil).present? }
|
303
354
|
end
|
355
|
+
self.inheritance_column = nil if inheritance_column && !columns_hash.key?(inheritance_column)
|
304
356
|
end
|
305
357
|
|
306
358
|
def _react_param_conversion(param, opt = nil)
|
307
359
|
param = Native(param)
|
308
360
|
param = JSON.from_object(param.to_n) if param.is_a? Native::Object
|
309
|
-
result =
|
310
|
-
param
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
if param[primary_key]
|
317
|
-
target = find(param[primary_key])
|
361
|
+
result =
|
362
|
+
if param.is_a? self
|
363
|
+
param
|
364
|
+
elsif param.is_a? Hash
|
365
|
+
if opt == :validate_only
|
366
|
+
klass = ReactiveRecord::Base.infer_type_from_hash(self, param)
|
367
|
+
klass == self || klass < self
|
318
368
|
else
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
end
|
326
|
-
if assoc
|
327
|
-
if value
|
328
|
-
[assoc.attribute, {id: [value], type: [nil]}]
|
369
|
+
# TODO: investigate saving .changes here and then replacing the
|
370
|
+
# TODO: changes after the load is complete. In other words preserve the
|
371
|
+
# TODO: changed values as changes while just updating the synced values.
|
372
|
+
target =
|
373
|
+
if param[primary_key]
|
374
|
+
find(param[primary_key])
|
329
375
|
else
|
330
|
-
|
376
|
+
new
|
331
377
|
end
|
332
|
-
else
|
333
|
-
[key, [value]]
|
334
|
-
end
|
335
|
-
end
|
336
378
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
379
|
+
associations = reflect_on_all_associations
|
380
|
+
|
381
|
+
param = param.collect do |key, value|
|
382
|
+
assoc = associations.detect do |association|
|
383
|
+
association.association_foreign_key == key
|
384
|
+
end
|
342
385
|
|
343
|
-
|
344
|
-
|
386
|
+
if assoc
|
387
|
+
if value
|
388
|
+
[assoc.attribute, { id: [value] }]
|
389
|
+
else
|
390
|
+
[assoc.attribute, [nil]]
|
391
|
+
end
|
392
|
+
else
|
393
|
+
[key, [value]]
|
394
|
+
end
|
395
|
+
end
|
396
|
+
# TODO: verify wrapping with load_data was added so broadcasting works in 1.0.0.lap28
|
397
|
+
ReactiveRecord::Base.load_data do
|
398
|
+
ReactiveRecord::ServerDataCache.load_from_json(Hash[param], target)
|
399
|
+
end
|
400
|
+
target.cast_to_current_sti_type
|
401
|
+
end
|
345
402
|
end
|
346
|
-
|
347
|
-
nil
|
348
|
-
end
|
403
|
+
|
349
404
|
result
|
350
405
|
end
|
351
|
-
|
352
406
|
end
|
353
|
-
|
354
407
|
end
|