hyper-mesh 1.0.0.lap27 → 1.0.0.lap28
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 +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
|