iknow_view_models 3.1.6 → 3.2.2
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/.circleci/config.yml +6 -6
- data/.rubocop.yml +18 -0
- data/Appraisals +6 -6
- data/Gemfile +6 -2
- data/Rakefile +5 -5
- data/gemfiles/rails_5_2.gemfile +5 -5
- data/gemfiles/rails_6_0.gemfile +9 -0
- data/iknow_view_models.gemspec +40 -38
- data/lib/iknow_view_models.rb +9 -7
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model.rb +31 -17
- data/lib/view_model/access_control.rb +5 -2
- data/lib/view_model/access_control/composed.rb +10 -9
- data/lib/view_model/access_control/open.rb +2 -0
- data/lib/view_model/access_control/read_only.rb +2 -0
- data/lib/view_model/access_control/tree.rb +11 -6
- data/lib/view_model/access_control_error.rb +4 -1
- data/lib/view_model/active_record.rb +13 -12
- data/lib/view_model/active_record/association_data.rb +3 -2
- data/lib/view_model/active_record/association_manipulation.rb +6 -4
- data/lib/view_model/active_record/cache.rb +114 -34
- data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
- data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
- data/lib/view_model/active_record/controller.rb +68 -1
- data/lib/view_model/active_record/controller_base.rb +4 -1
- data/lib/view_model/active_record/nested_controller_base.rb +1 -0
- data/lib/view_model/active_record/update_context.rb +8 -6
- data/lib/view_model/active_record/update_data.rb +32 -30
- data/lib/view_model/active_record/update_operation.rb +17 -13
- data/lib/view_model/active_record/visitor.rb +0 -1
- data/lib/view_model/after_transaction_runner.rb +2 -2
- data/lib/view_model/callbacks.rb +3 -1
- data/lib/view_model/controller.rb +13 -3
- data/lib/view_model/deserialization_error.rb +15 -12
- data/lib/view_model/error.rb +12 -10
- data/lib/view_model/error_view.rb +3 -1
- data/lib/view_model/migratable_view.rb +78 -0
- data/lib/view_model/migration.rb +48 -0
- data/lib/view_model/migration/no_path_error.rb +26 -0
- data/lib/view_model/migration/one_way_error.rb +24 -0
- data/lib/view_model/migration/unspecified_version_error.rb +24 -0
- data/lib/view_model/migrator.rb +108 -0
- data/lib/view_model/record.rb +15 -14
- data/lib/view_model/reference.rb +3 -1
- data/lib/view_model/references.rb +8 -5
- data/lib/view_model/registry.rb +1 -1
- data/lib/view_model/schemas.rb +9 -4
- data/lib/view_model/serialization_error.rb +4 -1
- data/lib/view_model/serialize_context.rb +4 -4
- data/lib/view_model/test_helpers.rb +8 -3
- data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
- data/lib/view_model/traversal_context.rb +2 -1
- data/nix/dependencies.nix +5 -0
- data/nix/gem/generate.rb +2 -1
- data/shell.nix +8 -3
- data/test/.rubocop.yml +14 -0
- data/test/helpers/arvm_test_models.rb +12 -9
- data/test/helpers/arvm_test_utilities.rb +5 -3
- data/test/helpers/controller_test_helpers.rb +55 -32
- data/test/helpers/match_enumerator.rb +1 -0
- data/test/helpers/query_logging.rb +2 -1
- data/test/helpers/test_access_control.rb +5 -3
- data/test/helpers/viewmodel_spec_helpers.rb +88 -22
- data/test/unit/view_model/access_control_test.rb +144 -144
- data/test/unit/view_model/active_record/alias_test.rb +15 -13
- data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
- data/test/unit/view_model/active_record/cache_test.rb +68 -31
- data/test/unit/view_model/active_record/cloner_test.rb +67 -63
- data/test/unit/view_model/active_record/controller_test.rb +113 -65
- data/test/unit/view_model/active_record/counter_test.rb +10 -9
- data/test/unit/view_model/active_record/customization_test.rb +59 -58
- data/test/unit/view_model/active_record/has_many_test.rb +112 -111
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
- data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
- data/test/unit/view_model/active_record/has_one_test.rb +37 -36
- data/test/unit/view_model/active_record/migration_test.rb +161 -0
- data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
- data/test/unit/view_model/active_record/poly_test.rb +44 -45
- data/test/unit/view_model/active_record/shared_test.rb +30 -28
- data/test/unit/view_model/active_record/version_test.rb +9 -7
- data/test/unit/view_model/active_record_test.rb +72 -72
- data/test/unit/view_model/callbacks_test.rb +19 -15
- data/test/unit/view_model/controller_test.rb +4 -2
- data/test/unit/view_model/record_test.rb +92 -97
- data/test/unit/view_model/traversal_context_test.rb +4 -5
- data/test/unit/view_model_test.rb +18 -16
- metadata +36 -12
- data/.travis.yml +0 -31
- data/appveyor.yml +0 -22
- data/gemfiles/rails_6_0_beta.gemfile +0 -9
data/nix/gem/generate.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
# This workaround is from https://github.com/manveru/bundix/issues/10#issuecomment-405879379
|
8
8
|
|
9
9
|
require 'shellwords'
|
10
|
+
require 'uri'
|
10
11
|
|
11
12
|
def sh(*args)
|
12
13
|
warn args.shelljoin
|
@@ -20,7 +21,7 @@ require 'bundler'
|
|
20
21
|
|
21
22
|
lockfile = Bundler::LockfileParser.new(File.read('Gemfile.lock'))
|
22
23
|
gems = lockfile.specs.select { |spec| spec.source.is_a?(Bundler::Source::Rubygems) }
|
23
|
-
sources =
|
24
|
+
sources = gems.map(&:source).flat_map(&:remotes).uniq
|
24
25
|
|
25
26
|
FileUtils.mkdir_p 'nix/gem'
|
26
27
|
Dir.chdir 'nix/gem' do
|
data/shell.nix
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
|
1
|
+
{ pkgs ? import <nixpkgs> {} }:
|
2
2
|
|
3
|
+
with pkgs;
|
4
|
+
|
5
|
+
let
|
6
|
+
dependencies = import ./nix/dependencies.nix { inherit pkgs; };
|
7
|
+
in
|
3
8
|
(bundlerEnv {
|
4
9
|
name = "iknow-view-models-shell";
|
5
10
|
gemdir = ./nix/gem;
|
6
11
|
|
7
|
-
gemConfig = (defaultGemConfig.override {
|
12
|
+
gemConfig = (defaultGemConfig.override { inherit (dependencies) postgresql; });
|
8
13
|
|
9
|
-
|
14
|
+
inherit (dependencies) ruby;
|
10
15
|
}).env
|
data/test/.rubocop.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
inherit_from: ../.rubocop.yml
|
2
|
+
|
3
|
+
Lint/NestedMethodDefinition:
|
4
|
+
Enabled: false
|
5
|
+
Lint/ConstantDefinitionInBlock:
|
6
|
+
Enabled: false
|
7
|
+
Layout/MultilineBlockLayout:
|
8
|
+
Enabled: false
|
9
|
+
Layout/HashAlignment:
|
10
|
+
Enabled: false
|
11
|
+
Layout/BlockEndNewline:
|
12
|
+
Enabled: false
|
13
|
+
Style/Semicolon:
|
14
|
+
Enabled: false
|
@@ -1,19 +1,22 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "view_model/active_record"
|
5
|
-
require "view_model/active_record/controller"
|
3
|
+
require_relative 'test_access_control'
|
6
4
|
|
7
|
-
require
|
5
|
+
require 'iknow_view_models'
|
6
|
+
require 'view_model/active_record'
|
7
|
+
require 'view_model/active_record/controller'
|
8
|
+
|
9
|
+
require 'acts_as_manual_list'
|
8
10
|
|
9
11
|
db_config_path = File.join(File.dirname(__FILE__), '../config/database.yml')
|
10
|
-
db_config = YAML.
|
11
|
-
raise
|
12
|
-
|
12
|
+
db_config = YAML.safe_load(File.open(db_config_path))
|
13
|
+
raise 'Test database configuration missing' unless db_config['test']
|
14
|
+
|
15
|
+
ActiveRecord::Base.establish_connection(db_config['test'])
|
13
16
|
|
14
17
|
# Remove test tables if any exist
|
15
18
|
%w[labels parents children targets poly_ones poly_twos owners
|
16
|
-
|
19
|
+
grand_parents categories tags parents_tags].each do |t|
|
17
20
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{t} CASCADE")
|
18
21
|
end
|
19
22
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support'
|
2
4
|
require 'minitest/hooks'
|
3
5
|
|
@@ -10,7 +12,7 @@ unless ViewModel::Config.configured?
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
require_relative 'query_logging
|
15
|
+
require_relative 'query_logging'
|
14
16
|
|
15
17
|
ActiveSupport::TestCase.include(Minitest::Hooks)
|
16
18
|
|
@@ -91,7 +93,7 @@ module ARVMTestUtilities
|
|
91
93
|
|
92
94
|
def enable_logging!
|
93
95
|
if ENV['DEBUG']
|
94
|
-
ActiveRecord::Base.logger = Logger.new(
|
96
|
+
ActiveRecord::Base.logger = Logger.new($stderr)
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -170,7 +172,7 @@ module ARVMTestUtilities
|
|
170
172
|
{
|
171
173
|
ViewModel::ActiveRecord::TYPE_ATTRIBUTE => type::NAME,
|
172
174
|
ViewModel::ActiveRecord::VALUES_ATTRIBUTE => values,
|
173
|
-
}.merge(rest.transform_keys(&:to_s))
|
175
|
+
}.merge(rest.transform_keys(&:to_s)),
|
174
176
|
)
|
175
177
|
end
|
176
178
|
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
2
|
-
require "view_model/active_record"
|
3
|
-
require "view_model/active_record/controller"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
require 'iknow_view_models'
|
4
|
+
require 'view_model/active_record'
|
5
|
+
require 'view_model/active_record/controller'
|
7
6
|
|
8
|
-
|
7
|
+
require_relative '../helpers/arvm_test_utilities'
|
8
|
+
require_relative '../helpers/arvm_test_models'
|
9
|
+
|
10
|
+
require 'action_controller'
|
11
|
+
|
12
|
+
require 'acts_as_manual_list'
|
9
13
|
|
10
14
|
# models for ARVM controller test
|
11
15
|
module ControllerTestModels
|
@@ -79,11 +83,25 @@ module ControllerTestModels
|
|
79
83
|
end
|
80
84
|
define_viewmodel do
|
81
85
|
root!
|
86
|
+
self.schema_version = 2
|
87
|
+
|
82
88
|
attributes :name
|
83
89
|
associations :label, :target
|
84
90
|
association :children
|
85
91
|
association :poly, viewmodels: [:PolyOne, :PolyTwo]
|
86
92
|
association :category, external: true
|
93
|
+
|
94
|
+
migrates from: 1, to: 2 do
|
95
|
+
up do |view, _refs|
|
96
|
+
if view.has_key?('old_name')
|
97
|
+
view['name'] = view.delete('old_name')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
down do |view, _refs|
|
102
|
+
view['old_name'] = view.delete('name')
|
103
|
+
end
|
104
|
+
end
|
87
105
|
end
|
88
106
|
end
|
89
107
|
|
@@ -129,27 +147,25 @@ end
|
|
129
147
|
|
130
148
|
## Dummy Rails Controllers
|
131
149
|
class DummyController
|
132
|
-
attr_reader :params, :status
|
150
|
+
attr_reader :params, :headers, :status
|
133
151
|
|
134
|
-
def initialize(
|
135
|
-
|
136
|
-
@
|
152
|
+
def initialize(headers: {}, params: {})
|
153
|
+
@params = ActionController::Parameters.new(params)
|
154
|
+
@headers = ActionDispatch::Http::Headers.from_hash({}).merge!(headers)
|
137
155
|
@status = 200
|
138
156
|
end
|
139
157
|
|
140
158
|
def invoke(method)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
self.instance_exec(ex, &handler)
|
152
|
-
end
|
159
|
+
self.public_send(method)
|
160
|
+
rescue StandardError => ex
|
161
|
+
handler = self.class.rescue_block(ex.class)
|
162
|
+
case handler
|
163
|
+
when nil
|
164
|
+
raise
|
165
|
+
when Symbol
|
166
|
+
self.send(handler, ex)
|
167
|
+
when Proc
|
168
|
+
self.instance_exec(ex, &handler)
|
153
169
|
end
|
154
170
|
end
|
155
171
|
|
@@ -169,7 +185,8 @@ class DummyController
|
|
169
185
|
end
|
170
186
|
|
171
187
|
def json_response
|
172
|
-
raise
|
188
|
+
raise 'Not a JSON response' unless @content_type == 'application/json'
|
189
|
+
|
173
190
|
@response_body
|
174
191
|
end
|
175
192
|
|
@@ -177,9 +194,15 @@ class DummyController
|
|
177
194
|
JSON.parse(json_response)
|
178
195
|
end
|
179
196
|
|
197
|
+
# for request.params and request.headers
|
198
|
+
def request
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
180
202
|
class << self
|
181
203
|
def inherited(subclass)
|
182
204
|
subclass.initialize_rescue_blocks
|
205
|
+
super
|
183
206
|
end
|
184
207
|
|
185
208
|
def initialize_rescue_blocks
|
@@ -191,11 +214,10 @@ class DummyController
|
|
191
214
|
end
|
192
215
|
|
193
216
|
def rescue_block(type)
|
194
|
-
@rescue_blocks.to_a.reverse.detect { |btype,
|
217
|
+
@rescue_blocks.to_a.reverse.detect { |btype, _h| type <= btype }.try(&:last)
|
195
218
|
end
|
196
219
|
|
197
|
-
def etag(*)
|
198
|
-
end
|
220
|
+
def etag(*); end
|
199
221
|
end
|
200
222
|
end
|
201
223
|
|
@@ -216,14 +238,15 @@ end
|
|
216
238
|
|
217
239
|
module CallbackTracing
|
218
240
|
attr_reader :callback_tracer
|
241
|
+
|
219
242
|
delegate :hook_trace, to: :callback_tracer
|
220
243
|
|
221
|
-
def new_deserialize_context(**
|
244
|
+
def new_deserialize_context(**_args)
|
222
245
|
@callback_tracer ||= CallbackTracer.new
|
223
246
|
super(callbacks: [@callback_tracer])
|
224
247
|
end
|
225
248
|
|
226
|
-
def new_serialize_context(**
|
249
|
+
def new_serialize_context(**_args)
|
227
250
|
@callback_tracer ||= CallbackTracer.new
|
228
251
|
super(callbacks: [@callback_tracer])
|
229
252
|
end
|
@@ -233,14 +256,14 @@ module ControllerTestControllers
|
|
233
256
|
def before_all
|
234
257
|
super
|
235
258
|
|
236
|
-
Class.new(DummyController) do |
|
259
|
+
Class.new(DummyController) do |_c|
|
237
260
|
Object.const_set(:ParentController, self)
|
238
261
|
include ViewModel::ActiveRecord::Controller
|
239
262
|
include CallbackTracing
|
240
263
|
self.access_control = ViewModel::AccessControl::Open
|
241
264
|
end
|
242
265
|
|
243
|
-
Class.new(DummyController) do |
|
266
|
+
Class.new(DummyController) do |_c|
|
244
267
|
Object.const_set(:ChildController, self)
|
245
268
|
include ViewModel::ActiveRecord::Controller
|
246
269
|
include CallbackTracing
|
@@ -248,7 +271,7 @@ module ControllerTestControllers
|
|
248
271
|
nested_in :parent, as: :children
|
249
272
|
end
|
250
273
|
|
251
|
-
Class.new(DummyController) do |
|
274
|
+
Class.new(DummyController) do |_c|
|
252
275
|
Object.const_set(:LabelController, self)
|
253
276
|
include ViewModel::ActiveRecord::Controller
|
254
277
|
include CallbackTracing
|
@@ -256,7 +279,7 @@ module ControllerTestControllers
|
|
256
279
|
nested_in :parent, as: :label
|
257
280
|
end
|
258
281
|
|
259
|
-
Class.new(DummyController) do |
|
282
|
+
Class.new(DummyController) do |_c|
|
260
283
|
Object.const_set(:TargetController, self)
|
261
284
|
include ViewModel::ActiveRecord::Controller
|
262
285
|
include CallbackTracing
|
@@ -14,6 +14,7 @@ module MiniTest::Assertions
|
|
14
14
|
|
15
15
|
def result
|
16
16
|
return false unless @actual.respond_to? :to_a
|
17
|
+
|
17
18
|
@extra_items = difference_between_enumerators(@actual, @expected)
|
18
19
|
@missing_items = difference_between_enumerators(@expected, @actual)
|
19
20
|
@extra_items.empty? & @missing_items.empty?
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Test mixin that allows queries executed in a block to be introspected.
|
2
4
|
#
|
3
5
|
# Code run within a `log_queries` block will collect data. Collected data is
|
@@ -9,7 +11,6 @@
|
|
9
11
|
require 'active_support/subscriber'
|
10
12
|
|
11
13
|
module QueryLogging
|
12
|
-
|
13
14
|
# ActiveRecord integration
|
14
15
|
class QueryLogger < ActiveSupport::Subscriber
|
15
16
|
@log = false
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'iknow_view_models'
|
3
4
|
|
4
5
|
class TestAccessControl < ViewModel::AccessControl
|
5
6
|
attr_accessor :editable_checks, :visible_checks
|
@@ -41,13 +42,14 @@ class TestAccessControl < ViewModel::AccessControl
|
|
41
42
|
def valid_edit_changes(ref)
|
42
43
|
all = all_valid_edit_changes(ref)
|
43
44
|
raise "Expected single change for ref '#{ref}'; found #{all}" unless all.size == 1
|
45
|
+
|
44
46
|
all.first
|
45
47
|
end
|
46
48
|
|
47
49
|
def all_valid_edit_changes(ref)
|
48
50
|
@valid_edit_checks
|
49
|
-
.select { |
|
50
|
-
.map { |_cref,
|
51
|
+
.select { |cref, _changes| cref == ref }
|
52
|
+
.map { |_cref, changes| changes }
|
51
53
|
end
|
52
54
|
|
53
55
|
def was_edited?(ref)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'view_model'
|
2
4
|
require 'view_model/test_helpers'
|
3
5
|
|
@@ -77,7 +79,7 @@ module ViewModelSpecHelpers
|
|
77
79
|
ViewModel::TestHelpers::ARVMBuilder::Spec.new(
|
78
80
|
schema: ->(t) { t.string :name },
|
79
81
|
model: ->(m) {},
|
80
|
-
viewmodel: ->(
|
82
|
+
viewmodel: ->(_v) { root!; attribute :name },
|
81
83
|
)
|
82
84
|
end
|
83
85
|
|
@@ -85,7 +87,7 @@ module ViewModelSpecHelpers
|
|
85
87
|
ViewModel::TestHelpers::ARVMBuilder::Spec.new(
|
86
88
|
schema: ->(t) { t.string :name },
|
87
89
|
model: ->(m) {},
|
88
|
-
viewmodel: ->(
|
90
|
+
viewmodel: ->(_v) { attribute :name },
|
89
91
|
)
|
90
92
|
end
|
91
93
|
|
@@ -120,12 +122,12 @@ module ViewModelSpecHelpers
|
|
120
122
|
def model_attributes
|
121
123
|
f = subject_association_features
|
122
124
|
super.merge(schema: ->(t) { t.references :child, foreign_key: true },
|
123
|
-
model: ->(
|
124
|
-
viewmodel: ->(
|
125
|
+
model: ->(_m) { belongs_to :child, inverse_of: :model, dependent: :destroy },
|
126
|
+
viewmodel: ->(_v) { association :child, **f })
|
125
127
|
end
|
126
128
|
|
127
129
|
def child_attributes
|
128
|
-
super.merge(model: ->(
|
130
|
+
super.merge(model: ->(_m) { has_one :model, inverse_of: :child })
|
129
131
|
end
|
130
132
|
|
131
133
|
# parent depends on child, ensure it's touched first
|
@@ -139,11 +141,76 @@ module ViewModelSpecHelpers
|
|
139
141
|
end
|
140
142
|
end
|
141
143
|
|
144
|
+
module ParentAndBelongsToChildWithMigration
|
145
|
+
extend ActiveSupport::Concern
|
146
|
+
include ViewModelSpecHelpers::ParentAndBelongsToChild
|
147
|
+
def model_attributes
|
148
|
+
super.merge(
|
149
|
+
schema: ->(t) { t.integer :new_field, default: 1, null: false },
|
150
|
+
viewmodel: ->(_v) {
|
151
|
+
self.schema_version = 4
|
152
|
+
|
153
|
+
attribute :new_field
|
154
|
+
|
155
|
+
# add: old_field (one-way)
|
156
|
+
migrates from: 1, to: 2 do
|
157
|
+
down do |view, _refs|
|
158
|
+
view.delete('old_field')
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# rename: old_field -> mid_field
|
163
|
+
migrates from: 2, to: 3 do
|
164
|
+
up do |view, _refs|
|
165
|
+
if view.has_key?('old_field')
|
166
|
+
view['mid_field'] = view.delete('old_field') + 1
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
down do |view, _refs|
|
171
|
+
view['old_field'] = view.delete('mid_field') - 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# rename: mid_field -> new_field
|
176
|
+
migrates from: 3, to: 4 do
|
177
|
+
up do |view, _refs|
|
178
|
+
if view.has_key?('mid_field')
|
179
|
+
view['new_field'] = view.delete('mid_field') + 1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
down do |view, _refs|
|
184
|
+
view['mid_field'] = view.delete('new_field') - 1
|
185
|
+
end
|
186
|
+
end
|
187
|
+
})
|
188
|
+
end
|
189
|
+
|
190
|
+
def child_attributes
|
191
|
+
super.merge(
|
192
|
+
viewmodel: ->(_v) {
|
193
|
+
self.schema_version = 3
|
194
|
+
|
195
|
+
# delete: former_field
|
196
|
+
migrates from: 2, to: 3 do
|
197
|
+
up do |view, _refs|
|
198
|
+
view.delete('former_field')
|
199
|
+
end
|
200
|
+
|
201
|
+
down do |view, _refs|
|
202
|
+
view['former_field'] = 'reconstructed'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
})
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
142
209
|
module ParentAndSharedBelongsToChild
|
143
210
|
extend ActiveSupport::Concern
|
144
211
|
include ViewModelSpecHelpers::ParentAndBelongsToChild
|
145
212
|
def child_attributes
|
146
|
-
super.merge(viewmodel: ->(
|
213
|
+
super.merge(viewmodel: ->(_v) { root! })
|
147
214
|
end
|
148
215
|
end
|
149
216
|
|
@@ -157,11 +224,11 @@ module ViewModelSpecHelpers
|
|
157
224
|
t.string :name
|
158
225
|
t.integer :next_id
|
159
226
|
},
|
160
|
-
model: ->(
|
227
|
+
model: ->(_m) {
|
161
228
|
belongs_to :next, class_name: self.name, inverse_of: :previous, dependent: :destroy
|
162
229
|
has_one :previous, class_name: self.name, foreign_key: :next_id, inverse_of: :next
|
163
230
|
},
|
164
|
-
viewmodel: ->(
|
231
|
+
viewmodel: ->(_v) {
|
165
232
|
# Not a root
|
166
233
|
association :next
|
167
234
|
attribute :name
|
@@ -180,15 +247,15 @@ module ViewModelSpecHelpers
|
|
180
247
|
def model_attributes
|
181
248
|
f = subject_association_features
|
182
249
|
super.merge(
|
183
|
-
model: ->(
|
184
|
-
viewmodel: ->(
|
250
|
+
model: ->(_m) { has_one :child, inverse_of: :model, dependent: :destroy },
|
251
|
+
viewmodel: ->(_v) { association :child, **f },
|
185
252
|
)
|
186
253
|
end
|
187
254
|
|
188
255
|
def child_attributes
|
189
256
|
super.merge(
|
190
257
|
schema: ->(t) { t.references :model, foreign_key: true },
|
191
|
-
model: ->(
|
258
|
+
model: ->(_m) { belongs_to :model, inverse_of: :child },
|
192
259
|
)
|
193
260
|
end
|
194
261
|
|
@@ -207,7 +274,7 @@ module ViewModelSpecHelpers
|
|
207
274
|
extend ActiveSupport::Concern
|
208
275
|
include ViewModelSpecHelpers::ParentAndHasOneChild
|
209
276
|
def child_attributes
|
210
|
-
super.merge(viewmodel: ->(
|
277
|
+
super.merge(viewmodel: ->(_v) { root! })
|
211
278
|
end
|
212
279
|
end
|
213
280
|
|
@@ -218,15 +285,15 @@ module ViewModelSpecHelpers
|
|
218
285
|
def model_attributes
|
219
286
|
f = subject_association_features
|
220
287
|
super.merge(
|
221
|
-
model: ->(
|
222
|
-
viewmodel: ->(
|
288
|
+
model: ->(_m) { has_many :children, inverse_of: :model, dependent: :destroy },
|
289
|
+
viewmodel: ->(_v) { association :children, **f },
|
223
290
|
)
|
224
291
|
end
|
225
292
|
|
226
293
|
def child_attributes
|
227
294
|
super.merge(
|
228
295
|
schema: ->(t) { t.references :model, foreign_key: true },
|
229
|
-
model: ->(
|
296
|
+
model: ->(_m) { belongs_to :model, inverse_of: :children },
|
230
297
|
)
|
231
298
|
end
|
232
299
|
|
@@ -245,7 +312,7 @@ module ViewModelSpecHelpers
|
|
245
312
|
extend ActiveSupport::Concern
|
246
313
|
include ViewModelSpecHelpers::ParentAndHasManyChildren
|
247
314
|
def child_attributes
|
248
|
-
super.merge(viewmodel: ->(
|
315
|
+
super.merge(viewmodel: ->(_v) { root! })
|
249
316
|
end
|
250
317
|
end
|
251
318
|
|
@@ -271,12 +338,11 @@ module ViewModelSpecHelpers
|
|
271
338
|
table = model.table_name
|
272
339
|
model.connection.execute <<-SQL
|
273
340
|
ALTER TABLE #{table} ADD CONSTRAINT #{table}_unique_on_model_and_position UNIQUE(model_id, position) DEFERRABLE INITIALLY DEFERRED
|
274
|
-
|
341
|
+
SQL
|
275
342
|
end
|
276
343
|
end
|
277
344
|
end
|
278
345
|
|
279
|
-
|
280
346
|
module ParentAndExternalSharedChild
|
281
347
|
extend ActiveSupport::Concern
|
282
348
|
include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
|
@@ -293,15 +359,15 @@ module ViewModelSpecHelpers
|
|
293
359
|
def model_attributes
|
294
360
|
f = subject_association_features
|
295
361
|
super.merge(
|
296
|
-
model: ->(
|
297
|
-
viewmodel: ->(
|
362
|
+
model: ->(_m) { has_many :model_children, inverse_of: :model, dependent: :destroy },
|
363
|
+
viewmodel: ->(_v) { association :children, through: :model_children, through_order_attr: :position, **f },
|
298
364
|
)
|
299
365
|
end
|
300
366
|
|
301
367
|
def child_attributes
|
302
368
|
super.merge(
|
303
|
-
model: ->(
|
304
|
-
viewmodel: ->(
|
369
|
+
model: ->(_m) { has_many :model_children, inverse_of: :child, dependent: :destroy },
|
370
|
+
viewmodel: ->(_v) { root! },
|
305
371
|
)
|
306
372
|
end
|
307
373
|
|