iknow_view_models 2.9.0 → 3.0.0
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/iknow_view_models.gemspec +1 -1
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model/active_record/association_data.rb +206 -92
- data/lib/view_model/active_record/association_manipulation.rb +22 -12
- data/lib/view_model/active_record/cache/cacheable_view.rb +3 -13
- data/lib/view_model/active_record/cache.rb +2 -2
- data/lib/view_model/active_record/cloner.rb +11 -11
- data/lib/view_model/active_record/controller.rb +0 -2
- data/lib/view_model/active_record/update_context.rb +21 -3
- data/lib/view_model/active_record/update_data.rb +43 -45
- data/lib/view_model/active_record/update_operation.rb +265 -153
- data/lib/view_model/active_record/visitor.rb +9 -6
- data/lib/view_model/active_record.rb +94 -74
- data/lib/view_model/after_transaction_runner.rb +3 -18
- data/lib/view_model/changes.rb +24 -16
- data/lib/view_model/config.rb +6 -2
- data/lib/view_model/deserialization_error.rb +31 -0
- data/lib/view_model/deserialize_context.rb +2 -6
- data/lib/view_model/error_view.rb +6 -5
- data/lib/view_model/record/attribute_data.rb +11 -6
- data/lib/view_model/record.rb +44 -24
- data/lib/view_model/serialize_context.rb +2 -63
- data/lib/view_model.rb +17 -8
- data/shell.nix +1 -1
- data/test/helpers/arvm_test_utilities.rb +6 -0
- data/test/helpers/controller_test_helpers.rb +5 -3
- data/test/helpers/viewmodel_spec_helpers.rb +63 -52
- data/test/unit/view_model/access_control_test.rb +88 -37
- data/test/unit/view_model/active_record/belongs_to_test.rb +110 -178
- data/test/unit/view_model/active_record/cache_test.rb +3 -2
- data/test/unit/view_model/active_record/cloner_test.rb +1 -1
- data/test/unit/view_model/active_record/controller_test.rb +12 -20
- data/test/unit/view_model/active_record/has_many_test.rb +540 -316
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +12 -15
- data/test/unit/view_model/active_record/has_many_through_test.rb +15 -58
- data/test/unit/view_model/active_record/has_one_test.rb +288 -135
- data/test/unit/view_model/active_record/poly_test.rb +0 -1
- data/test/unit/view_model/active_record/shared_test.rb +21 -39
- data/test/unit/view_model/active_record/version_test.rb +3 -2
- data/test/unit/view_model/active_record_test.rb +5 -63
- data/test/unit/view_model/callbacks_test.rb +1 -0
- data/test/unit/view_model/record_test.rb +0 -32
- data/test/unit/view_model/traversal_context_test.rb +13 -12
- metadata +5 -8
- data/test/unit/view_model/active_record/optional_attribute_view_test.rb +0 -58
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'renum'
|
2
4
|
require 'view_model/schemas'
|
3
5
|
|
@@ -45,14 +47,13 @@ class ViewModel::ActiveRecord
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
# Parser for collection updates. Collection updates have a regular
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
# reference strings.
|
50
|
+
# Parser for collection updates. Collection updates have a regular structure,
|
51
|
+
# but vary based on the contents. Parsing a nested collection recurses deeply
|
52
|
+
# and creates a tree of UpdateDatas, while parsing a referenced collection
|
53
|
+
# collects reference strings.
|
53
54
|
class AbstractCollectionUpdate
|
54
|
-
# Wraps a complete collection of new data: either UpdateDatas for
|
55
|
-
#
|
55
|
+
# Wraps a complete collection of new data: either UpdateDatas for non-root
|
56
|
+
# associations or reference strings for root.
|
56
57
|
class Replace
|
57
58
|
attr_reader :contents
|
58
59
|
def initialize(contents)
|
@@ -61,7 +62,8 @@ class ViewModel::ActiveRecord
|
|
61
62
|
end
|
62
63
|
|
63
64
|
# Wraps an ordered list of FunctionalUpdates, each of whose `contents` are
|
64
|
-
# either UpdateData for
|
65
|
+
# either UpdateData for nested associations or references for referenced
|
66
|
+
# associations.
|
65
67
|
class Functional
|
66
68
|
attr_reader :actions
|
67
69
|
def initialize(actions)
|
@@ -81,8 +83,8 @@ class ViewModel::ActiveRecord
|
|
81
83
|
|
82
84
|
# Resolve ViewModel::References used in the update's contents, whether by
|
83
85
|
# reference or value.
|
84
|
-
def used_vm_refs(
|
85
|
-
raise
|
86
|
+
def used_vm_refs(_update_context)
|
87
|
+
raise RuntimeError.new('abstract method')
|
86
88
|
end
|
87
89
|
|
88
90
|
def removed_vm_refs
|
@@ -153,7 +155,8 @@ class ViewModel::ActiveRecord
|
|
153
155
|
# The shape of the actions are always the same
|
154
156
|
|
155
157
|
# Parse an anchor for a functional_update, before/after
|
156
|
-
# May only contain type and id fields, is never a reference even for
|
158
|
+
# May only contain type and id fields, is never a reference even for
|
159
|
+
# referenced associations.
|
157
160
|
def parse_anchor(child_hash) # final
|
158
161
|
child_metadata = ViewModel.extract_reference_only_metadata(child_hash)
|
159
162
|
|
@@ -271,9 +274,13 @@ class ViewModel::ActiveRecord
|
|
271
274
|
|
272
275
|
def used_vm_refs(update_context)
|
273
276
|
update_datas
|
274
|
-
.map { |upd| upd
|
277
|
+
.map { |upd| resolve_vm_reference(upd, update_context) }
|
275
278
|
.compact
|
276
279
|
end
|
280
|
+
|
281
|
+
def resolve_vm_reference(update_data, _update_context)
|
282
|
+
update_data.viewmodel_reference if update_data.id
|
283
|
+
end
|
277
284
|
end
|
278
285
|
|
279
286
|
class Parser < AbstractCollectionUpdate::Parser
|
@@ -319,9 +326,13 @@ class ViewModel::ActiveRecord
|
|
319
326
|
|
320
327
|
def used_vm_refs(update_context)
|
321
328
|
references.map do |ref|
|
322
|
-
|
329
|
+
resolve_vm_reference(ref, update_context)
|
323
330
|
end
|
324
331
|
end
|
332
|
+
|
333
|
+
def resolve_vm_reference(ref, update_context)
|
334
|
+
update_context.resolve_reference(ref, nil).viewmodel_reference
|
335
|
+
end
|
325
336
|
end
|
326
337
|
|
327
338
|
class Parser < AbstractCollectionUpdate::Parser
|
@@ -356,6 +367,7 @@ class ViewModel::ActiveRecord
|
|
356
367
|
unless valid_reference_keys.include?(ref)
|
357
368
|
raise ViewModel::DeserializationError::InvalidSharedReference.new(ref, blame_reference)
|
358
369
|
end
|
370
|
+
|
359
371
|
ref
|
360
372
|
end
|
361
373
|
end
|
@@ -421,7 +433,7 @@ class ViewModel::ActiveRecord
|
|
421
433
|
fupdate_owned =
|
422
434
|
fupdate_base.(ViewModel::Schemas::VIEWMODEL_UPDATE_SCHEMA)
|
423
435
|
|
424
|
-
fupdate_shared
|
436
|
+
fupdate_shared =
|
425
437
|
fupdate_base.({ 'oneOf' => [ViewModel::Schemas::VIEWMODEL_REFERENCE_SCHEMA,
|
426
438
|
viewmodel_reference_only] })
|
427
439
|
|
@@ -571,30 +583,15 @@ class ViewModel::ActiveRecord
|
|
571
583
|
case
|
572
584
|
when value.nil?
|
573
585
|
[]
|
574
|
-
when association_data.
|
586
|
+
when association_data.referenced?
|
575
587
|
[]
|
576
|
-
when association_data.collection? #
|
588
|
+
when association_data.collection? # nested, because of referenced? check above
|
577
589
|
value.update_datas
|
578
590
|
else
|
579
591
|
[value]
|
580
592
|
end
|
581
593
|
end
|
582
594
|
|
583
|
-
# Updates in terms of viewmodel associations
|
584
|
-
def updated_associations
|
585
|
-
deps = {}
|
586
|
-
|
587
|
-
(associations.merge(referenced_associations)).each do |assoc_name, assoc_update|
|
588
|
-
deps[assoc_name] =
|
589
|
-
to_sequence(assoc_name, assoc_update)
|
590
|
-
.each_with_object({}) do |update_data, updated_associations|
|
591
|
-
updated_associations.deep_merge!(update_data.updated_associations)
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
deps
|
596
|
-
end
|
597
|
-
|
598
595
|
def build_preload_specs(association_data, updates)
|
599
596
|
if association_data.polymorphic?
|
600
597
|
updates.map do |update_data|
|
@@ -682,6 +679,7 @@ class ViewModel::ActiveRecord
|
|
682
679
|
|
683
680
|
when AssociationData
|
684
681
|
association_data = member_data
|
682
|
+
|
685
683
|
case
|
686
684
|
when value.nil?
|
687
685
|
if association_data.collection?
|
@@ -689,28 +687,28 @@ class ViewModel::ActiveRecord
|
|
689
687
|
"Invalid collection update value 'nil' for association '#{name}'",
|
690
688
|
blame_reference)
|
691
689
|
end
|
692
|
-
if association_data.
|
690
|
+
if association_data.referenced?
|
693
691
|
referenced_associations[name] = nil
|
694
692
|
else
|
695
693
|
associations[name] = nil
|
696
694
|
end
|
697
695
|
|
698
|
-
when association_data.
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
696
|
+
when association_data.referenced?
|
697
|
+
if association_data.collection?
|
698
|
+
referenced_associations[name] =
|
699
|
+
ReferencedCollectionUpdate::Parser
|
700
|
+
.new(association_data, blame_reference, valid_reference_keys)
|
701
|
+
.parse(value)
|
702
|
+
else
|
703
|
+
# Extract and check reference
|
704
|
+
ref = ViewModel.extract_reference_metadata(value)
|
703
705
|
|
704
|
-
|
705
|
-
|
706
|
-
|
706
|
+
unless valid_reference_keys.include?(ref)
|
707
|
+
raise ViewModel::DeserializationError::InvalidSharedReference.new(ref, blame_reference)
|
708
|
+
end
|
707
709
|
|
708
|
-
|
709
|
-
raise ViewModel::DeserializationError::InvalidSharedReference.new(ref, blame_reference)
|
710
|
+
referenced_associations[name] = ref
|
710
711
|
end
|
711
|
-
|
712
|
-
referenced_associations[name] = ref
|
713
|
-
|
714
712
|
else
|
715
713
|
if association_data.collection?
|
716
714
|
associations[name] =
|