iknow_view_models 3.8.0 → 3.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10ac2bba9965a5eb683cdbb972d1a7c8b31a6fd86304b1e52816cdd5649818d9
4
- data.tar.gz: dcd13cba67c3b27beb4491b23d6a487ff30a3a3b930a8d2188a5503f77298c89
3
+ metadata.gz: c6e6ce3aa96f51d7453e79412026e0d3bc840fbac2bcf8c19603564b158ea8a9
4
+ data.tar.gz: 7ded42908be86bf155b95325af28577dad6e9e4b3f030a14db6753a7b05146bc
5
5
  SHA512:
6
- metadata.gz: a0faccad196615ad236d93016b3268fe50c3eac86bfc52750445a53655fc24d24ff068442071d4ea0a6d1d19e86cdaba8ae24ad9cba5d4feedfbb007333217e9
7
- data.tar.gz: 253dea949f2c1a79360969fbd662a93d072ef93ff43554b5b08bc65344e2cc96c58b0eea2a71ff734cd8d3507c07b2569638be4d483c116d7b498ea98aca5fd5
6
+ metadata.gz: fb370a1c5d85fe6f3ea9037ef79e006548d691eb45a6db275e4b97040a76b27f65e6af6f29c1de7e2759792343e37c000dac7cd2accf420bfe199fef11b531ab
7
+ data.tar.gz: e16ef99251d41057f0a897e7e1ba3215715c27cb3d0b6ab5aa769df9656fa617fae410944fa45daac8e243929086bbf10c7a8472c890eb1320b9e2c719b246a4
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IknowViewModels
4
- VERSION = '3.8.0'
4
+ VERSION = '3.9.0'
5
5
  end
@@ -14,8 +14,7 @@ class ViewModel::ActiveRecord
14
14
 
15
15
  attr_accessor :viewmodel,
16
16
  :update_data,
17
- :points_to, # AssociationData => UpdateOperation (returns single new viewmodel to update fkey)
18
- :pointed_to, # AssociationData => UpdateOperation(s) (returns viewmodel(s) with which to update assoc cache)
17
+ :association_updates, # AssociationData => UpdateOperation(s)
19
18
  :reparent_to, # If node needs to update its pointer to a new parent, ParentData for the parent
20
19
  :reposition_to, # if this node participates in a list under its parent, what should its position be?
21
20
  :released_children # Set of children that have been released
@@ -23,13 +22,12 @@ class ViewModel::ActiveRecord
23
22
  delegate :attributes, to: :update_data
24
23
 
25
24
  def initialize(viewmodel, update_data, reparent_to: nil, reposition_to: nil)
26
- self.viewmodel = viewmodel
27
- self.update_data = update_data
28
- self.points_to = {}
29
- self.pointed_to = {}
30
- self.reparent_to = reparent_to
31
- self.reposition_to = reposition_to
32
- self.released_children = []
25
+ self.viewmodel = viewmodel
26
+ self.update_data = update_data
27
+ self.association_updates = {}
28
+ self.reparent_to = reparent_to
29
+ self.reposition_to = reposition_to
30
+ self.released_children = []
33
31
 
34
32
  @run_state = RunState::Pending
35
33
  @changed_associations = []
@@ -82,46 +80,47 @@ class ViewModel::ActiveRecord
82
80
  end
83
81
 
84
82
  # Visit attributes and associations as much as possible in the order
85
- # that they're declared in the view.
86
- member_ordering = viewmodel.class._members.keys.each_with_index.to_h
87
-
88
- # update user-specified attributes
89
- attribute_keys = attributes.keys.sort_by { |k| member_ordering[k] }
90
- attribute_keys.each do |attr_name|
91
- serialized_value = attributes[attr_name]
92
-
93
- # Note that the VM::AR deserialization tree asserts ownership over any
94
- # references it's provided, and so they're intentionally not passed on
95
- # to attribute deserialization for use by their `using:` viewmodels. A
96
- # (better?) alternative would be to provide them as reference-only
97
- # hashes, to indicate that no modification can be permitted.
98
- viewmodel.public_send("deserialize_#{attr_name}", serialized_value,
99
- references: {},
100
- deserialize_context: deserialize_context)
83
+ # that they're declared in the view. We can visit attributes and
84
+ # points-to associations before save, but points-from associations
85
+ # must be visited after save.
86
+ pre_save_members, post_save_members = viewmodel.class._members.values.partition do |member_data|
87
+ !member_data.association? || member_data.pointer_location == :local
101
88
  end
102
89
 
103
- # Update points-to associations before save
104
- points_to_keys = points_to.keys.sort_by do |association_data|
105
- member_ordering[association_data.association_name]
106
- end
90
+ pre_save_members.each do |member_data|
91
+ if member_data.association?
92
+ next unless association_updates.include?(member_data)
107
93
 
108
- points_to_keys.each do |association_data|
109
- child_operation = points_to[association_data]
94
+ child_operation = association_updates[member_data]
110
95
 
111
- reflection = association_data.direct_reflection
112
- debug "-> #{debug_name}: Updating points-to association '#{reflection.name}'"
96
+ reflection = member_data.direct_reflection
97
+ debug "-> #{debug_name}: Updating points-to association '#{reflection.name}'"
113
98
 
114
- association = model.association(reflection.name)
115
- new_target =
116
- if child_operation
117
- child_ctx = viewmodel.context_for_child(association_data.association_name, context: deserialize_context)
118
- child_viewmodel = child_operation.run!(deserialize_context: child_ctx)
119
- propagate_tree_changes(association_data, child_viewmodel.previous_changes)
99
+ association = model.association(reflection.name)
100
+ new_target =
101
+ if child_operation
102
+ child_ctx = viewmodel.context_for_child(member_data.association_name, context: deserialize_context)
103
+ child_viewmodel = child_operation.run!(deserialize_context: child_ctx)
104
+ propagate_tree_changes(member_data, child_viewmodel.previous_changes)
120
105
 
121
- child_viewmodel.model
122
- end
123
- association.writer(new_target)
124
- debug "<- #{debug_name}: Updated points-to association '#{reflection.name}'"
106
+ child_viewmodel.model
107
+ end
108
+ association.writer(new_target)
109
+ debug "<- #{debug_name}: Updated points-to association '#{reflection.name}'"
110
+ else
111
+ attr_name = member_data.name
112
+ next unless attributes.include?(attr_name)
113
+
114
+ serialized_value = attributes[attr_name]
115
+ # Note that the VM::AR deserialization tree asserts ownership over any
116
+ # references it's provided, and so they're intentionally not passed on
117
+ # to attribute deserialization for use by their `using:` viewmodels. A
118
+ # (better?) alternative would be to provide them as reference-only
119
+ # hashes, to indicate that no modification can be permitted.
120
+ viewmodel.public_send("deserialize_#{attr_name}", serialized_value,
121
+ references: {},
122
+ deserialize_context: deserialize_context)
123
+ end
125
124
  end
126
125
 
127
126
  # validate
@@ -144,12 +143,10 @@ class ViewModel::ActiveRecord
144
143
 
145
144
  # Update association cache of pointed-from associations after save: the
146
145
  # child update will have saved the pointer.
147
- pointed_to_keys = pointed_to.keys.sort_by do |association_data|
148
- member_ordering[association_data.association_name]
149
- end
146
+ post_save_members.each do |association_data|
147
+ next unless association_updates.include?(association_data)
150
148
 
151
- pointed_to_keys.each do |association_data|
152
- child_operation = pointed_to[association_data]
149
+ child_operation = association_updates[association_data]
153
150
  reflection = association_data.direct_reflection
154
151
 
155
152
  debug "-> #{debug_name}: Updating pointed-to association '#{reflection.name}'"
@@ -265,13 +262,7 @@ class ViewModel::ActiveRecord
265
262
  end
266
263
 
267
264
  def add_update(association_data, update)
268
- target =
269
- case association_data.pointer_location
270
- when :remote then pointed_to
271
- when :local then points_to
272
- end
273
-
274
- target[association_data] = update
265
+ self.association_updates[association_data] = update
275
266
  end
276
267
 
277
268
  private
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: 3.8.0
4
+ version: 3.9.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: 2024-01-24 00:00:00.000000000 Z
11
+ date: 2024-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack