iknow_view_models 2.10.1 → 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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +119 -0
  3. data/.travis.yml +31 -0
  4. data/Appraisals +6 -16
  5. data/gemfiles/{rails_7_0.gemfile → rails_6_0_beta.gemfile} +2 -2
  6. data/iknow_view_models.gemspec +3 -5
  7. data/lib/iknow_view_models/version.rb +1 -1
  8. data/lib/view_model/active_record/association_data.rb +206 -92
  9. data/lib/view_model/active_record/association_manipulation.rb +22 -12
  10. data/lib/view_model/active_record/cache/cacheable_view.rb +3 -13
  11. data/lib/view_model/active_record/cache.rb +2 -2
  12. data/lib/view_model/active_record/cloner.rb +11 -11
  13. data/lib/view_model/active_record/controller.rb +0 -2
  14. data/lib/view_model/active_record/update_context.rb +21 -3
  15. data/lib/view_model/active_record/update_data.rb +43 -45
  16. data/lib/view_model/active_record/update_operation.rb +265 -153
  17. data/lib/view_model/active_record/visitor.rb +9 -6
  18. data/lib/view_model/active_record.rb +94 -74
  19. data/lib/view_model/after_transaction_runner.rb +3 -18
  20. data/lib/view_model/callbacks.rb +2 -2
  21. data/lib/view_model/changes.rb +24 -16
  22. data/lib/view_model/config.rb +6 -2
  23. data/lib/view_model/deserialization_error.rb +31 -0
  24. data/lib/view_model/deserialize_context.rb +2 -6
  25. data/lib/view_model/error_view.rb +6 -5
  26. data/lib/view_model/record/attribute_data.rb +11 -6
  27. data/lib/view_model/record.rb +44 -24
  28. data/lib/view_model/serialize_context.rb +2 -63
  29. data/lib/view_model/test_helpers/arvm_builder.rb +2 -4
  30. data/lib/view_model/traversal_context.rb +2 -2
  31. data/lib/view_model.rb +21 -13
  32. data/shell.nix +1 -1
  33. data/test/helpers/arvm_test_models.rb +4 -12
  34. data/test/helpers/arvm_test_utilities.rb +6 -0
  35. data/test/helpers/controller_test_helpers.rb +6 -6
  36. data/test/helpers/viewmodel_spec_helpers.rb +63 -52
  37. data/test/unit/view_model/access_control_test.rb +88 -37
  38. data/test/unit/view_model/active_record/belongs_to_test.rb +110 -178
  39. data/test/unit/view_model/active_record/cache_test.rb +11 -5
  40. data/test/unit/view_model/active_record/cloner_test.rb +1 -1
  41. data/test/unit/view_model/active_record/controller_test.rb +12 -20
  42. data/test/unit/view_model/active_record/has_many_test.rb +540 -316
  43. data/test/unit/view_model/active_record/has_many_through_poly_test.rb +12 -15
  44. data/test/unit/view_model/active_record/has_many_through_test.rb +15 -58
  45. data/test/unit/view_model/active_record/has_one_test.rb +288 -135
  46. data/test/unit/view_model/active_record/poly_test.rb +0 -1
  47. data/test/unit/view_model/active_record/shared_test.rb +21 -39
  48. data/test/unit/view_model/active_record/version_test.rb +3 -2
  49. data/test/unit/view_model/active_record_test.rb +5 -63
  50. data/test/unit/view_model/callbacks_test.rb +1 -0
  51. data/test/unit/view_model/record_test.rb +0 -32
  52. data/test/unit/view_model/traversal_context_test.rb +13 -12
  53. metadata +15 -25
  54. data/.github/workflows/gem-push.yml +0 -31
  55. data/.github/workflows/test.yml +0 -65
  56. data/gemfiles/rails_6_0.gemfile +0 -9
  57. data/gemfiles/rails_6_1.gemfile +0 -9
  58. data/test/unit/view_model/active_record/optional_attribute_view_test.rb +0 -58
@@ -22,6 +22,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
22
22
  end
23
23
 
24
24
  define_viewmodel do
25
+ root!
25
26
  attributes :name
26
27
  end
27
28
  end
@@ -43,8 +44,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
43
44
  end
44
45
 
45
46
  define_viewmodel do
47
+ root!
46
48
  attributes :name
47
- association :category, shared: true, optional: true
49
+ association :category
48
50
  end
49
51
  end
50
52
  end
@@ -66,16 +68,11 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
66
68
  enable_logging!
67
69
  end
68
70
 
69
- def serialize_context
70
- ParentView.new_serialize_context(include: :category)
71
- end
72
-
73
71
  def test_loading_batching
74
72
  Parent.create(category: Category.new)
75
73
 
76
74
  log_queries do
77
- serialize(ParentView.load(serialize_context: serialize_context),
78
- serialize_context: serialize_context)
75
+ serialize(ParentView.load())
79
76
  end
80
77
  assert_equal(['Parent Load', 'Category Load'],
81
78
  logged_load_queries)
@@ -104,7 +101,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
104
101
  end
105
102
 
106
103
  def test_serialize_view
107
- view, refs = serialize_with_references(ParentView.new(@parent1), serialize_context: serialize_context)
104
+ view, refs = serialize_with_references(ParentView.new(@parent1))
108
105
  cat1_ref = refs.detect { |_, v| v['_type'] == 'Category' }.first
109
106
 
110
107
  assert_equal({cat1_ref => { '_type' => "Category",
@@ -122,20 +119,14 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
122
119
  end
123
120
 
124
121
  def test_shared_eager_include
125
- parent_includes = ParentView.eager_includes
126
-
127
- assert_equal(DeepPreloader::Spec.new, parent_includes)
128
-
129
- extra_includes = ParentView.eager_includes(serialize_context: ParentView.new_serialize_context(include: :category))
130
-
131
- assert_equal(DeepPreloader::Spec.new('category' => DeepPreloader::Spec.new), extra_includes)
122
+ includes = ParentView.eager_includes
123
+ assert_equal(DeepPreloader::Spec.new('category' => DeepPreloader::Spec.new), includes)
132
124
  end
133
125
 
134
126
  def test_shared_serialize_interning
135
127
  @parent2.update(category: @parent1.category)
136
128
  view, refs = serialize_with_references([ParentView.new(@parent1),
137
- ParentView.new(@parent2)],
138
- serialize_context: ParentView.new_serialize_context(include: :category))
129
+ ParentView.new(@parent2)])
139
130
 
140
131
  category_ref = view.first['category']['_ref']
141
132
 
@@ -144,7 +135,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
144
135
  end
145
136
 
146
137
  def test_shared_add_reference
147
- alter_by_view!(ParentView, @parent2, serialize_context: serialize_context) do |p2view, refs|
138
+ alter_by_view!(ParentView, @parent2) do |p2view, refs|
148
139
  p2view['category'] = { '_ref' => 'myref' }
149
140
  refs['myref'] = update_hash_for(CategoryView, @category1)
150
141
  end
@@ -153,7 +144,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
153
144
  end
154
145
 
155
146
  def test_shared_add_multiple_references
156
- alter_by_view!(ParentView, [@parent1, @parent2], serialize_context: serialize_context) do |(p1view, p2view), refs|
147
+ alter_by_view!(ParentView, [@parent1, @parent2]) do |(p1view, p2view), refs|
157
148
  refs.delete(p1view['category']['_ref'])
158
149
  refs['myref'] = update_hash_for(CategoryView, @category1)
159
150
 
@@ -167,7 +158,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
167
158
 
168
159
  def test_shared_requires_all_references
169
160
  ex = assert_raises(ViewModel::DeserializationError::InvalidStructure) do
170
- alter_by_view!(ParentView, @parent2, serialize_context: serialize_context) do |p2view, refs|
161
+ alter_by_view!(ParentView, @parent2) do |p2view, refs|
171
162
  refs['spurious_ref'] = { '_type' => 'Parent', 'id' => @parent1.id }
172
163
  end
173
164
  end
@@ -176,8 +167,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
176
167
 
177
168
  def test_shared_requires_valid_references
178
169
  assert_raises(ViewModel::DeserializationError::InvalidSharedReference) do
179
- serialize_context = ParentView.new_serialize_context(include: :category)
180
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
170
+ alter_by_view!(ParentView, @parent1) do |p1view, refs|
181
171
  refs.clear # remove the expected serialized refs
182
172
  end
183
173
  end
@@ -185,8 +175,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
185
175
 
186
176
  def test_shared_requires_assignable_type
187
177
  ex = assert_raises(ViewModel::DeserializationError::InvalidAssociationType) do
188
- serialize_context = ParentView.new_serialize_context(include: :category)
189
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
178
+ alter_by_view!(ParentView, @parent1) do |p1view, refs|
190
179
  p1view['category'] = { '_ref' => 'p2' }
191
180
  refs['p2'] = update_hash_for(ParentView, @parent2)
192
181
  end
@@ -195,10 +184,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
195
184
  end
196
185
 
197
186
  def test_shared_requires_unique_references
198
- serialize_context = ParentView.new_serialize_context(include: :category)
199
187
  c1_ref = update_hash_for(CategoryView, @category1)
200
188
  assert_raises(ViewModel::DeserializationError::DuplicateNodes) do
201
- alter_by_view!(ParentView, [@parent1, @parent2], serialize_context: serialize_context) do |(p1view, p2view), refs|
189
+ alter_by_view!(ParentView, [@parent1, @parent2]) do |(p1view, p2view), refs|
202
190
  refs['c_a'] = c1_ref.dup
203
191
  refs['c_b'] = c1_ref.dup
204
192
  p1view['category'] = { '_ref' => 'c_a' }
@@ -208,8 +196,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
208
196
  end
209
197
 
210
198
  def test_shared_updates_shared_data
211
- serialize_context = ParentView.new_serialize_context(include: :category)
212
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
199
+ alter_by_view!(ParentView, @parent1) do |p1view, refs|
213
200
  category_ref = p1view['category']['_ref']
214
201
  refs[category_ref]['name'] = 'newcatname'
215
202
  end
@@ -217,8 +204,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
217
204
  end
218
205
 
219
206
  def test_shared_delete_reference
220
- serialize_context = ParentView.new_serialize_context(include: :category)
221
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
207
+ alter_by_view!(ParentView, @parent1) do |p1view, refs|
222
208
  category_ref = p1view['category']['_ref']
223
209
  refs.delete(category_ref)
224
210
  p1view['category'] = nil
@@ -228,10 +214,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
228
214
  end
229
215
 
230
216
  def test_child_edit_doesnt_editcheck_parent
231
- serialize_context = ParentView.new_serialize_context(include: :category)
232
217
  d_context = ParentView.new_deserialize_context
233
218
 
234
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context, deserialize_context: d_context) do |view, refs|
219
+ alter_by_view!(ParentView, @parent1, deserialize_context: d_context) do |view, refs|
235
220
  refs[view['category']["_ref"]]["name"] = "changed"
236
221
  end
237
222
 
@@ -240,9 +225,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
240
225
  end
241
226
 
242
227
  def test_child_change_editchecks_parent
243
- s_context = ParentView.new_serialize_context(include: :category)
244
-
245
- nv, d_context = alter_by_view!(ParentView, @parent1, serialize_context: s_context) do |view, refs|
228
+ nv, d_context = alter_by_view!(ParentView, @parent1) do |view, refs|
246
229
  refs.delete(view['category']['_ref'])
247
230
  view['category']['_ref'] = 'new_cat'
248
231
  refs['new_cat'] = { '_type' => 'Category', 'name' => 'new category' }
@@ -253,10 +236,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
253
236
  end
254
237
 
255
238
  def test_child_delete_editchecks_parent
256
- serialize_context = ParentView.new_serialize_context(include: :category)
257
239
  d_context = ParentView.new_deserialize_context
258
240
 
259
- alter_by_view!(ParentView, @parent1, serialize_context: serialize_context, deserialize_context: d_context) do |view, refs|
241
+ alter_by_view!(ParentView, @parent1, deserialize_context: d_context) do |view, refs|
260
242
  refs.delete(view['category']['_ref'])
261
243
  view['category'] = nil
262
244
  end
@@ -268,7 +250,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
268
250
  deps = ParentView.dependent_viewmodels
269
251
  assert_equal([ParentView, CategoryView].to_set, deps)
270
252
 
271
- deps = ParentView.dependent_viewmodels(include_shared: false)
253
+ deps = ParentView.dependent_viewmodels(include_referenced: false)
272
254
  assert_equal([ParentView].to_set, deps)
273
255
  end
274
256
 
@@ -278,7 +260,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
278
260
  CategoryView.view_name => CategoryView.schema_version },
279
261
  vers)
280
262
 
281
- vers = ParentView.deep_schema_version(include_shared: false)
263
+ vers = ParentView.deep_schema_version(include_referenced: false)
282
264
  assert_equal({ ParentView.view_name => ParentView.schema_version },
283
265
  vers)
284
266
  end
@@ -21,13 +21,13 @@ class ViewModel::ActiveRecord::VersionTest < ActiveSupport::TestCase
21
21
  end
22
22
  end
23
23
 
24
-
25
24
  build_viewmodel(:Target) do
26
25
  define_schema {}
27
26
  define_model do
28
27
  has_one :parent, inverse_of: :target
29
28
  end
30
29
  define_viewmodel do
30
+ root!
31
31
  self.schema_version = 20
32
32
  end
33
33
  end
@@ -44,8 +44,9 @@ class ViewModel::ActiveRecord::VersionTest < ActiveSupport::TestCase
44
44
  end
45
45
  define_viewmodel do
46
46
  self.schema_version = 5
47
+ root!
47
48
  association :child, viewmodels: [:ChildA]
48
- association :target, shared: true, optional: false
49
+ association :target
49
50
  end
50
51
  end
51
52
  end
@@ -17,7 +17,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
17
17
  build_viewmodel(:Trivial) do
18
18
  define_schema
19
19
  define_model {}
20
- define_viewmodel {}
20
+ define_viewmodel { root! }
21
21
  end
22
22
 
23
23
  build_viewmodel(:Parent) do
@@ -35,6 +35,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
35
35
  end
36
36
 
37
37
  define_viewmodel do
38
+ root!
38
39
  attributes :name, :lock_version
39
40
  attribute :one, read_only: true
40
41
  end
@@ -376,66 +377,6 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
376
377
  end
377
378
  end
378
379
 
379
- # Tests for functionality common to all ARVM instances, but require some kind
380
- # of relationship.
381
- class RelationshipTests < ActiveSupport::TestCase
382
- include ARVMTestUtilities
383
-
384
- def before_all
385
- super
386
-
387
- build_viewmodel(:Parent) do
388
- define_schema do |t|
389
- t.string :name
390
- end
391
-
392
- define_model do
393
- has_many :children, dependent: :destroy, inverse_of: :parent
394
- end
395
-
396
- define_viewmodel do
397
- attributes :name
398
- associations :children
399
- end
400
- end
401
-
402
- build_viewmodel(:Child) do
403
- define_schema do |t|
404
- t.references :parent, null: false, foreign_key: true
405
- t.string :name
406
- end
407
-
408
- define_model do
409
- belongs_to :parent, inverse_of: :children
410
- end
411
-
412
- define_viewmodel do
413
- attributes :name
414
- end
415
- end
416
- end
417
-
418
- def test_updated_associations_returned
419
- # This test ensures the data is passed back through the context. The tests
420
- # for the values are in the relationship-specific tests.
421
-
422
- updated_by_view = ->(view) do
423
- context = ViewModelBase.new_deserialize_context
424
- ParentView.deserialize_from_view(view, deserialize_context: context)
425
- context.updated_associations
426
- end
427
-
428
- assert_equal({},
429
- updated_by_view.({ '_type' => 'Parent',
430
- 'name' => 'p' }))
431
-
432
- assert_equal({ 'children' => {} },
433
- updated_by_view.({ '_type' => 'Parent',
434
- 'name' => 'p',
435
- 'children' => [] }))
436
- end
437
- end
438
-
439
380
  # Parent view should be correctly passed down the tree when deserializing
440
381
  class DeserializationParentContextTest < ActiveSupport::TestCase
441
382
  include ARVMTestUtilities
@@ -499,7 +440,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
499
440
  end
500
441
  end
501
442
 
502
- # Parent view should be correctly passed down the tree when deserializing
443
+ # Parent view should be correctly passed down the tree when deserializing
503
444
  class DeferredConstraintTest < ActiveSupport::TestCase
504
445
  include ARVMTestUtilities
505
446
 
@@ -516,7 +457,8 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
516
457
  end
517
458
 
518
459
  define_viewmodel do
519
- association :child, shared: true
460
+ root!
461
+ association :child
520
462
  end
521
463
  end
522
464
  List.connection.execute("ALTER TABLE lists ADD CONSTRAINT unique_child UNIQUE (child_id) DEFERRABLE INITIALLY DEFERRED")
@@ -348,6 +348,7 @@ class ViewModel::CallbacksTest < ActiveSupport::TestCase
348
348
  alter_by_view!(viewmodel_class, vm.model) do |view, _refs|
349
349
  view['next'] = nil
350
350
  end
351
+
351
352
  value(callback.hook_trace).must_equal(
352
353
  [
353
354
  visit(ViewModel::Callbacks::Hook::BeforeVisit, vm),
@@ -204,12 +204,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
204
204
  assert_equal("unknown", ex.attribute)
205
205
  end
206
206
 
207
- it "can prune an attribute" do
208
- h = viewmodel_class.new(default_model).to_hash(serialize_context: TestSerializeContext.new(prune: [:simple]))
209
- pruned_view = default_view.tap { |v| v.delete("simple") }
210
- assert_equal(pruned_view, h)
211
- end
212
-
213
207
  it "edit checks when creating empty" do
214
208
  vm = viewmodel_class.deserialize_from_view(view_base, deserialize_context: create_context)
215
209
  refute(default_model.equal?(vm.model), "returned model was the same")
@@ -377,24 +371,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
377
371
  end
378
372
  end
379
373
 
380
- describe "with optional attributes" do
381
- let(:attributes) { { optional: { optional: true } } }
382
-
383
- include CanDeserializeToNew
384
- include CanDeserializeToExisting
385
-
386
- it "can serialize with the optional attribute" do
387
- h = viewmodel_class.new(default_model).to_hash(serialize_context: TestSerializeContext.new(include: [:optional]))
388
- assert_equal(default_view, h)
389
- end
390
-
391
- it "can serialize without the optional attribute" do
392
- h = viewmodel_class.new(default_model).to_hash
393
- pruned_view = default_view.tap { |v| v.delete("optional") }
394
- assert_equal(pruned_view, h)
395
- end
396
- end
397
-
398
374
  Nested = Struct.new(:member)
399
375
 
400
376
  class NestedView < TestViewModel
@@ -448,14 +424,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
448
424
  assert_edited(vm, new: false, changed_attributes: [:nested])
449
425
  assert_edited(vm.nested, new: true, changed_attributes: [:member])
450
426
  end
451
-
452
- it "can prune attributes in the nested value" do
453
- h = viewmodel_class.new(default_model).to_hash(
454
- serialize_context: TestSerializeContext.new(prune: { nested: [:member] }))
455
-
456
- pruned_view = default_view.tap { |v| v["nested"].delete("member") }
457
- assert_equal(pruned_view, h)
458
- end
459
427
  end
460
428
 
461
429
  describe "with array of nested viewmodel" do
@@ -35,6 +35,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
35
35
  after_visit do
36
36
  ref = view.to_reference
37
37
  raise RuntimeError.new('Visited twice') if details.has_key?(ref)
38
+
38
39
  details[ref] = ContextDetail.new(
39
40
  context.parent_viewmodel&.to_reference,
40
41
  context.parent_association,
@@ -87,12 +88,12 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
87
88
  # models have no more than one shared association, and if present it is the
88
89
  # one under test.
89
90
  def clear_subject_association(view, refs)
90
- refs.clear if subject_association.shared?
91
+ refs.clear if subject_association.referenced?
91
92
  view[subject_association_name] = subject_association.collection? ? [] : nil
92
93
  end
93
94
 
94
95
  def set_subject_association(view, refs, value)
95
- if subject_association.shared?
96
+ if subject_association.referenced?
96
97
  refs.clear
97
98
  value = convert_to_refs(refs, value)
98
99
  end
@@ -100,7 +101,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
100
101
  end
101
102
 
102
103
  def add_to_subject_association(view, refs, value)
103
- if subject_association.shared?
104
+ if subject_association.referenced?
104
105
  value = convert_to_refs(refs, value)
105
106
  end
106
107
  view[subject_association_name] << value
@@ -108,12 +109,12 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
108
109
 
109
110
  def remove_from_subject_association(view, refs)
110
111
  view[subject_association_name].reject! do |child|
111
- if subject_association.shared?
112
+ if subject_association.referenced?
112
113
  ref = child[ViewModel::REFERENCE_ATTRIBUTE]
113
114
  child = refs[ref]
114
115
  end
115
116
  match = yield(child)
116
- if match && subject_association.shared?
117
+ if match && subject_association.referenced?
117
118
  refs.delete(ref)
118
119
  end
119
120
  match
@@ -167,7 +168,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
167
168
  end
168
169
 
169
170
  expected = expected_parent_details
170
- expected = expected.merge(expected_children_details) unless subject_association.shared?
171
+ expected = expected.merge(expected_children_details) unless subject_association.referenced?
171
172
  assert_traversal_matches(expected, context_recorder.details)
172
173
  end
173
174
 
@@ -179,7 +180,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
179
180
  end
180
181
 
181
182
  expected = expected_parent_details
182
- expected = expected.merge(expected_children_details) unless subject_association.shared?
183
+ expected = expected.merge(expected_children_details) unless subject_association.referenced?
183
184
  expected = expected.merge(new_child_expected_details)
184
185
  assert_traversal_matches(expected, context_recorder.details)
185
186
  end
@@ -190,7 +191,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
190
191
  vm.replace_associated(subject_association_name, replacement, deserialize_context: ctx)
191
192
 
192
193
  expected = expected_parent_details
193
- expected = expected.merge(expected_children_details) unless subject_association.shared?
194
+ expected = expected.merge(expected_children_details) unless subject_association.referenced?
194
195
  expected = expected.merge(new_child_expected_details)
195
196
  assert_traversal_matches(expected, context_recorder.details)
196
197
  end
@@ -224,7 +225,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
224
225
  end
225
226
 
226
227
  expected = expected_parent_details.merge(expected_children_details)
227
- expected = expected.except(removed_child.to_reference) if subject_association.shared?
228
+ expected = expected.except(removed_child.to_reference) if subject_association.referenced?
228
229
  assert_traversal_matches(expected, context_recorder.details)
229
230
  end
230
231
 
@@ -241,7 +242,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
241
242
  vm.delete_associated(subject_association_name, removed_child.id, deserialize_context: ctx)
242
243
 
243
244
  expected = expected_parent_details
244
- expected = expected.merge(removed_child_expected_details) unless subject_association.shared?
245
+ expected = expected.merge(removed_child_expected_details) unless subject_association.referenced?
245
246
  assert_traversal_matches(expected, context_recorder.details)
246
247
  end
247
248
  end
@@ -265,7 +266,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
265
266
 
266
267
  let(:root_detail) { ContextDetail.new(nil, nil, true) }
267
268
  let(:child_detail) do
268
- if subject_association.shared?
269
+ if subject_association.referenced?
269
270
  root_detail
270
271
  else
271
272
  ContextDetail.new(vm.to_reference, subject_association_name, false)
@@ -346,7 +347,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
346
347
  end
347
348
 
348
349
  describe 'with parent and shared child' do
349
- include ViewModelSpecHelpers::ParentAndSharedChild
350
+ include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
350
351
 
351
352
  include BehavesLikeSerialization
352
353
  include BehavesLikeDeserialization
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iknow_view_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iKnow Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-23 00:00:00.000000000 Z
11
+ date: 2019-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 1.0.1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 1.0.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: iknow_cache
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -84,22 +84,16 @@ dependencies:
84
84
  name: iknow_params
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: 2.2.0
90
- - - "<"
91
- - !ruby/object:Gem::Version
92
- version: '2.4'
93
90
  type: :runtime
94
91
  prerelease: false
95
92
  version_requirements: !ruby/object:Gem::Requirement
96
93
  requirements:
97
- - - ">="
94
+ - - "~>"
98
95
  - !ruby/object:Gem::Version
99
96
  version: 2.2.0
100
- - - "<"
101
- - !ruby/object:Gem::Version
102
- version: '2.4'
103
97
  - !ruby/object:Gem::Dependency
104
98
  name: safe_values
105
99
  requirement: !ruby/object:Gem::Requirement
@@ -286,16 +280,16 @@ dependencies:
286
280
  name: pg
287
281
  requirement: !ruby/object:Gem::Requirement
288
282
  requirements:
289
- - - ">="
283
+ - - "~>"
290
284
  - !ruby/object:Gem::Version
291
- version: '0'
285
+ version: '0.18'
292
286
  type: :development
293
287
  prerelease: false
294
288
  version_requirements: !ruby/object:Gem::Requirement
295
289
  requirements:
296
- - - ">="
290
+ - - "~>"
297
291
  - !ruby/object:Gem::Version
298
- version: '0'
292
+ version: '0.18'
299
293
  - !ruby/object:Gem::Dependency
300
294
  name: pry
301
295
  requirement: !ruby/object:Gem::Requirement
@@ -359,11 +353,11 @@ executables: []
359
353
  extensions: []
360
354
  extra_rdoc_files: []
361
355
  files:
356
+ - ".circleci/config.yml"
362
357
  - ".envrc"
363
- - ".github/workflows/gem-push.yml"
364
- - ".github/workflows/test.yml"
365
358
  - ".gitignore"
366
359
  - ".idea/codeStyleSettings.xml"
360
+ - ".travis.yml"
367
361
  - Appraisals
368
362
  - Gemfile
369
363
  - LICENSE.txt
@@ -371,9 +365,7 @@ files:
371
365
  - Rakefile
372
366
  - appveyor.yml
373
367
  - gemfiles/rails_5_2.gemfile
374
- - gemfiles/rails_6_0.gemfile
375
- - gemfiles/rails_6_1.gemfile
376
- - gemfiles/rails_7_0.gemfile
368
+ - gemfiles/rails_6_0_beta.gemfile
377
369
  - iknow_view_models.gemspec
378
370
  - lib/iknow_view_models.rb
379
371
  - lib/iknow_view_models/railtie.rb
@@ -446,7 +438,6 @@ files:
446
438
  - test/unit/view_model/active_record/has_many_through_test.rb
447
439
  - test/unit/view_model/active_record/has_one_test.rb
448
440
  - test/unit/view_model/active_record/namespacing_test.rb
449
- - test/unit/view_model/active_record/optional_attribute_view_test.rb
450
441
  - test/unit/view_model/active_record/poly_test.rb
451
442
  - test/unit/view_model/active_record/shared_test.rb
452
443
  - test/unit/view_model/active_record/version_test.rb
@@ -469,14 +460,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
469
460
  requirements:
470
461
  - - ">="
471
462
  - !ruby/object:Gem::Version
472
- version: 2.7.3
463
+ version: '0'
473
464
  required_rubygems_version: !ruby/object:Gem::Requirement
474
465
  requirements:
475
466
  - - ">="
476
467
  - !ruby/object:Gem::Version
477
468
  version: '0'
478
469
  requirements: []
479
- rubygems_version: 3.1.6
470
+ rubygems_version: 3.0.3
480
471
  signing_key:
481
472
  specification_version: 4
482
473
  summary: ViewModels provide a means of encapsulating a collection of related data
@@ -504,7 +495,6 @@ test_files:
504
495
  - test/unit/view_model/active_record/has_many_through_test.rb
505
496
  - test/unit/view_model/active_record/has_one_test.rb
506
497
  - test/unit/view_model/active_record/namespacing_test.rb
507
- - test/unit/view_model/active_record/optional_attribute_view_test.rb
508
498
  - test/unit/view_model/active_record/poly_test.rb
509
499
  - test/unit/view_model/active_record/shared_test.rb
510
500
  - test/unit/view_model/active_record/version_test.rb
@@ -1,31 +0,0 @@
1
- name: Publish Ruby Gem
2
-
3
- on:
4
- push:
5
- branches: [ "v2.x" ]
6
-
7
- jobs:
8
- build:
9
- name: Build + Publish
10
- runs-on: ubuntu-latest
11
- permissions:
12
- contents: read
13
- packages: write
14
-
15
- steps:
16
- - uses: actions/checkout@v3
17
- - name: Set up Ruby 2.7
18
- uses: ruby/setup-ruby@v1
19
- with:
20
- ruby-version: 2.7
21
-
22
- - name: Publish to RubyGems
23
- run: |
24
- mkdir -p $HOME/.gem
25
- touch $HOME/.gem/credentials
26
- chmod 0600 $HOME/.gem/credentials
27
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
28
- gem build *.gemspec
29
- gem push *.gem
30
- env:
31
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"