active_record_compose 0.8.1 → 0.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 +4 -4
- data/CHANGELOG.md +5 -3
- data/README.md +2 -47
- data/lib/active_record_compose/delegate_attribute.rb +2 -2
- data/lib/active_record_compose/model.rb +16 -217
- data/lib/active_record_compose/transaction_support.rb +1 -1
- data/lib/active_record_compose/version.rb +1 -1
- data/lib/active_record_compose.rb +0 -12
- data/sig/_internal/package_private.rbs +1 -1
- data/sig/active_record_compose.rbs +3 -6
- metadata +3 -20
- data/UPGRADE.md +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dba7d13bf8f2dc9ef449ead00c1a7ae3fff83e216f07b5d11606659a3c1f4650
|
4
|
+
data.tar.gz: 883a9480ff3e6bd4c99246c12200a7b5a6e44103c0d1c967ce97c4536aa478b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 905bf7969733f738e00726f0dc7ed1442bce1f598485a72a0478fd67069c556b5d8299fdc5485636b1194e095649df550ba9f3c01ffb42c107a8a69afcde85ae
|
7
|
+
data.tar.gz: 22f44a63d515d31682f22641e112c3bf720c5b3ff29c8fb0a30ceb777b23847a74f053eb3591211c35bfe2e2f96de345523236d08b30365059fc3a7421437bf4
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.
|
3
|
+
## [0.9.0] - 2025-03-16
|
4
4
|
|
5
|
-
-
|
6
|
-
-
|
5
|
+
- removed `persisted_flag_callback_control` support.
|
6
|
+
- Omitted `:private` option from `delegate_attribute` because, assuming the
|
7
|
+
behavior and use cases of `ActiveModel::Attributes.attribute`, making it private is unnecessary.
|
8
|
+
- Added the URL for the sample application to the README
|
7
9
|
|
8
10
|
## [0.8.0] - 2025-02-22
|
9
11
|
|
data/README.md
CHANGED
@@ -286,18 +286,11 @@ end
|
|
286
286
|
|
287
287
|
### Callback ordering by `#persisted?`
|
288
288
|
|
289
|
-
The behavior of `(before|after|around)_create` and `(before|after|around)_update` hooks
|
290
|
-
the state of the `persisted_flag_callback_control` setting.
|
291
|
-
default value is `true`, behavior when set to `false` will be removed in the next release.
|
292
|
-
|
293
|
-
When `persisted_flag_callback_control` is set to `true`, it behaves almost like callback control in ActiveRecord.
|
294
|
-
Depending on the evaluation result of `#persisted?`,
|
289
|
+
The behavior of `(before|after|around)_create` and `(before|after|around)_update` hooks depending on the evaluation result of `#persisted?`,
|
295
290
|
either the create-related callbacks or the update-related callbacks will be triggered.
|
296
291
|
|
297
292
|
```ruby
|
298
293
|
class ComposedModel < ActiveRecordCompose::Model
|
299
|
-
self.persisted_flag_callback_control = true # In the future, true will be the default and false will no longer be supported.
|
300
|
-
|
301
294
|
# ...
|
302
295
|
|
303
296
|
before_save { puts 'before_save called!' }
|
@@ -345,48 +338,10 @@ model.save # or `model.update` (the same callbacks will be triggered in all case
|
|
345
338
|
# after_save called!
|
346
339
|
```
|
347
340
|
|
348
|
-
When `persisted_flag_callback_control` is set to false,
|
349
|
-
the execution of `#create`, `#update`, or `#save` determines which callbacks will be triggered.
|
350
|
-
This behavior will no longer be supported in the next release.
|
351
|
-
|
352
|
-
```ruby
|
353
|
-
class ComposedModel < ActiveRecordCompose::Model
|
354
|
-
self.persisted_flag_callback_control = false # Currently defaults to false, but will no longer be supported in the future.
|
355
|
-
|
356
|
-
# ...
|
357
|
-
|
358
|
-
before_save { puts 'before_save called!' }
|
359
|
-
before_create { puts 'before_create called!' }
|
360
|
-
before_update { puts 'before_update called!' }
|
361
|
-
after_save { puts 'after_save called!' }
|
362
|
-
after_create { puts 'after_create called!' }
|
363
|
-
after_update { puts 'after_update called!' }
|
364
|
-
end
|
365
|
-
```
|
366
|
-
|
367
|
-
```ruby
|
368
|
-
model = ComposedModel.new
|
369
|
-
|
370
|
-
model.save
|
371
|
-
# before_save called!
|
372
|
-
# after_save called!
|
373
|
-
|
374
|
-
model.create
|
375
|
-
# before_save called!
|
376
|
-
# before_create called!
|
377
|
-
# after_create called!
|
378
|
-
# after_save called!
|
379
|
-
|
380
|
-
model.update
|
381
|
-
# before_save called!
|
382
|
-
# before_update called!
|
383
|
-
# after_update called!
|
384
|
-
# after_save called!
|
385
|
-
```
|
386
|
-
|
387
341
|
## Links
|
388
342
|
|
389
343
|
- [Smart way to update multiple models simultaneously in Rails](https://dev.to/hamajyotan/smart-way-to-update-multiple-models-simultaneously-in-rails-51b6)
|
344
|
+
- [Sample application as an example](https://github.com/hamajyotan/active_record_compose-example)
|
390
345
|
|
391
346
|
## Development
|
392
347
|
|
@@ -45,7 +45,7 @@ module ActiveRecordCompose
|
|
45
45
|
module ClassMethods
|
46
46
|
# Defines the reader and writer for the specified attribute.
|
47
47
|
#
|
48
|
-
def delegate_attribute(*attributes, to:, allow_nil: nil
|
48
|
+
def delegate_attribute(*attributes, to:, allow_nil: nil)
|
49
49
|
delegates = attributes.flat_map do |attribute|
|
50
50
|
reader = attribute.to_s
|
51
51
|
writer = "#{attribute}="
|
@@ -53,7 +53,7 @@ module ActiveRecordCompose
|
|
53
53
|
[reader, writer]
|
54
54
|
end
|
55
55
|
|
56
|
-
delegate(*delegates, to:, allow_nil
|
56
|
+
delegate(*delegates, to:, allow_nil:)
|
57
57
|
self.delegated_attributes = delegated_attributes.to_a + attributes.map { _1.to_s }
|
58
58
|
end
|
59
59
|
end
|
@@ -15,46 +15,6 @@ module ActiveRecordCompose
|
|
15
15
|
include ActiveRecordCompose::DelegateAttribute
|
16
16
|
include ActiveRecordCompose::TransactionSupport
|
17
17
|
|
18
|
-
# This flag controls the callback sequence for models.
|
19
|
-
# The current default value is `true`, behavior when set to `false` will be removed in the next release.
|
20
|
-
#
|
21
|
-
# When `persisted_flag_callback_control` is set to `true`,
|
22
|
-
# the occurrence of callbacks depends on the evaluation result of `#persisted?`.
|
23
|
-
# Additionally, the definition of `#persisted?` itself can be appropriately overridden in subclasses.
|
24
|
-
#
|
25
|
-
# if `#persisted?` returns `false`:
|
26
|
-
# * before_save
|
27
|
-
# * before_create
|
28
|
-
# * after_create
|
29
|
-
# * after_save
|
30
|
-
#
|
31
|
-
# if `#persisted?` returns `true`:
|
32
|
-
# * before_save
|
33
|
-
# * before_update
|
34
|
-
# * after_update
|
35
|
-
# * after_save
|
36
|
-
#
|
37
|
-
# On the other hand, when `persisted_flag_callback_control` is set to `false`,
|
38
|
-
# the invoked methods during saving operations vary depending on the method used.
|
39
|
-
#
|
40
|
-
# when performing `#save` or `#save!`:
|
41
|
-
# * before_save
|
42
|
-
# * after_save
|
43
|
-
#
|
44
|
-
# when performing `#update` or `#update!`:
|
45
|
-
# * before_save
|
46
|
-
# * before_update
|
47
|
-
# * after_update
|
48
|
-
# * after_save
|
49
|
-
#
|
50
|
-
# when performing `#create` or `#create!`:
|
51
|
-
# * before_save
|
52
|
-
# * before_create
|
53
|
-
# * after_create
|
54
|
-
# * after_save
|
55
|
-
#
|
56
|
-
class_attribute :persisted_flag_callback_control, instance_accessor: false, default: true
|
57
|
-
|
58
18
|
define_model_callbacks :save
|
59
19
|
define_model_callbacks :create
|
60
20
|
define_model_callbacks :update
|
@@ -70,24 +30,16 @@ module ActiveRecordCompose
|
|
70
30
|
#
|
71
31
|
# The save is performed within a single transaction.
|
72
32
|
#
|
33
|
+
# Options like `:validate` and `:context` are not accepted as arguments.
|
34
|
+
# The need for such values indicates that operations from multiple contexts are being handled.
|
35
|
+
# However, if the contexts are different, it is recommended to separate them into different model definitions.
|
36
|
+
#
|
73
37
|
# @return [Boolean] returns true on success, false on failure.
|
74
38
|
def save
|
75
39
|
return false if invalid?
|
76
40
|
|
77
41
|
with_transaction_returning_status do
|
78
|
-
|
79
|
-
with_callbacks { save_models(bang: false) }
|
80
|
-
else
|
81
|
-
# steep:ignore:start
|
82
|
-
deprecator.warn(
|
83
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
84
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
85
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
86
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
87
|
-
)
|
88
|
-
# steep:ignore:end
|
89
|
-
run_callbacks(:save) { save_models(bang: false) }
|
90
|
-
end
|
42
|
+
with_callbacks { save_models(bang: false) }
|
91
43
|
rescue ActiveRecord::RecordInvalid
|
92
44
|
false
|
93
45
|
end
|
@@ -98,170 +50,31 @@ module ActiveRecordCompose
|
|
98
50
|
#
|
99
51
|
# Saving, like `#save`, is performed within a single transaction.
|
100
52
|
#
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
with_transaction_returning_status do
|
105
|
-
if self.class.persisted_flag_callback_control
|
106
|
-
with_callbacks { save_models(bang: true) }
|
107
|
-
else
|
108
|
-
# steep:ignore:start
|
109
|
-
deprecator.warn(
|
110
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
111
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
112
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
113
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
114
|
-
)
|
115
|
-
# steep:ignore:end
|
116
|
-
run_callbacks(:save) { save_models(bang: true) }
|
117
|
-
end
|
118
|
-
end || raise_on_save_error
|
119
|
-
end
|
120
|
-
|
121
|
-
# Behavior is same to `#save`, but `before_create` and `after_create` hooks fires.
|
122
|
-
#
|
123
|
-
# class ComposedModel < ActiveRecordCompose::Model
|
124
|
-
# # ...
|
125
|
-
#
|
126
|
-
# before_save { puts 'before_save called!' }
|
127
|
-
# before_create { puts 'before_create called!' }
|
128
|
-
# before_update { puts 'before_update called!' }
|
129
|
-
# after_save { puts 'after_save called!' }
|
130
|
-
# after_create { puts 'after_create called!' }
|
131
|
-
# after_update { puts 'after_update called!' }
|
132
|
-
# end
|
133
|
-
#
|
134
|
-
# model = ComposedModel.new
|
53
|
+
# Options like `:validate` and `:context` are not accepted as arguments.
|
54
|
+
# The need for such values indicates that operations from multiple contexts are being handled.
|
55
|
+
# However, if the contexts are different, it is recommended to separate them into different model definitions.
|
135
56
|
#
|
136
|
-
|
137
|
-
# # before_save called!
|
138
|
-
# # after_save called!
|
139
|
-
#
|
140
|
-
# model.create
|
141
|
-
# # before_save called!
|
142
|
-
# # before_create called!
|
143
|
-
# # after_create called!
|
144
|
-
# # after_save called!
|
145
|
-
#
|
146
|
-
# @deprecated
|
147
|
-
def create(attributes = {})
|
148
|
-
if self.class.persisted_flag_callback_control
|
149
|
-
raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
|
150
|
-
end
|
151
|
-
|
152
|
-
# steep:ignore:start
|
153
|
-
deprecator.warn(
|
154
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
155
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
156
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
157
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
158
|
-
)
|
159
|
-
# steep:ignore:end
|
160
|
-
|
161
|
-
assign_attributes(attributes)
|
162
|
-
return false if invalid?
|
163
|
-
|
164
|
-
with_transaction_returning_status do
|
165
|
-
with_callbacks(context: :create) { save_models(bang: false) }
|
166
|
-
rescue ActiveRecord::RecordInvalid
|
167
|
-
false
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Behavior is same to `#create`, but raises an exception prematurely on failure.
|
172
|
-
#
|
173
|
-
# @deprecated
|
174
|
-
def create!(attributes = {})
|
175
|
-
if self.class.persisted_flag_callback_control
|
176
|
-
raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
|
177
|
-
end
|
178
|
-
|
179
|
-
# steep:ignore:start
|
180
|
-
deprecator.warn(
|
181
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
182
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
183
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
184
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
185
|
-
)
|
186
|
-
# steep:ignore:end
|
187
|
-
|
188
|
-
assign_attributes(attributes)
|
57
|
+
def save!
|
189
58
|
valid? || raise_validation_error
|
190
59
|
|
191
60
|
with_transaction_returning_status do
|
192
|
-
with_callbacks
|
61
|
+
with_callbacks { save_models(bang: true) }
|
193
62
|
end || raise_on_save_error
|
194
63
|
end
|
195
64
|
|
196
|
-
#
|
197
|
-
#
|
198
|
-
# class ComposedModel < ActiveRecordCompose::Model
|
199
|
-
# # ...
|
200
|
-
#
|
201
|
-
# before_save { puts 'before_save called!' }
|
202
|
-
# before_create { puts 'before_create called!' }
|
203
|
-
# before_update { puts 'before_update called!' }
|
204
|
-
# after_save { puts 'after_save called!' }
|
205
|
-
# after_create { puts 'after_create called!' }
|
206
|
-
# after_update { puts 'after_update called!' }
|
207
|
-
# end
|
208
|
-
#
|
209
|
-
# model = ComposedModel.new
|
210
|
-
#
|
211
|
-
# model.save
|
212
|
-
# # before_save called!
|
213
|
-
# # after_save called!
|
214
|
-
#
|
215
|
-
# model.update
|
216
|
-
# # before_save called!
|
217
|
-
# # before_update called!
|
218
|
-
# # after_update called!
|
219
|
-
# # after_save called!
|
65
|
+
# Assign attributes and save.
|
220
66
|
#
|
67
|
+
# @return [Boolean] returns true on success, false on failure.
|
221
68
|
def update(attributes = {})
|
222
69
|
assign_attributes(attributes)
|
223
|
-
|
224
|
-
|
225
|
-
with_transaction_returning_status do
|
226
|
-
if self.class.persisted_flag_callback_control
|
227
|
-
with_callbacks { save_models(bang: false) }
|
228
|
-
else
|
229
|
-
# steep:ignore:start
|
230
|
-
deprecator.warn(
|
231
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
232
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
233
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
234
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
235
|
-
)
|
236
|
-
# steep:ignore:end
|
237
|
-
with_callbacks(context: :update) { save_models(bang: false) }
|
238
|
-
end
|
239
|
-
rescue ActiveRecord::RecordInvalid
|
240
|
-
false
|
241
|
-
end
|
70
|
+
save
|
242
71
|
end
|
243
72
|
|
244
73
|
# Behavior is same to `#update`, but raises an exception prematurely on failure.
|
245
74
|
#
|
246
75
|
def update!(attributes = {})
|
247
76
|
assign_attributes(attributes)
|
248
|
-
|
249
|
-
|
250
|
-
with_transaction_returning_status do
|
251
|
-
if self.class.persisted_flag_callback_control
|
252
|
-
with_callbacks { save_models(bang: true) }
|
253
|
-
else
|
254
|
-
# steep:ignore:start
|
255
|
-
deprecator.warn(
|
256
|
-
'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
|
257
|
-
'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
|
258
|
-
'(Alternatively, exclude statements that set `false`) ' \
|
259
|
-
'cf. https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md ',
|
260
|
-
)
|
261
|
-
# steep:ignore:end
|
262
|
-
with_callbacks(context: :update) { save_models(bang: true) }
|
263
|
-
end
|
264
|
-
end || raise_on_save_error
|
77
|
+
save!
|
265
78
|
end
|
266
79
|
|
267
80
|
# Returns true if model is persisted.
|
@@ -281,13 +94,9 @@ module ActiveRecordCompose
|
|
281
94
|
models.__wrapped_models.lazy.select { _1.invalid? }.each { errors.merge!(_1) }
|
282
95
|
end
|
283
96
|
|
284
|
-
def with_callbacks(
|
285
|
-
run_callbacks(:save) { run_callbacks(callback_context(context:), &block) }
|
286
|
-
end
|
97
|
+
def with_callbacks(&block) = run_callbacks(:save) { run_callbacks(callback_context, &block) }
|
287
98
|
|
288
|
-
def callback_context
|
289
|
-
context || (persisted? ? :update : :create)
|
290
|
-
end
|
99
|
+
def callback_context = persisted? ? :update : :create
|
291
100
|
|
292
101
|
def save_models(bang:)
|
293
102
|
models.__wrapped_models.all? { bang ? _1.save! : _1.save }
|
@@ -298,15 +107,5 @@ module ActiveRecordCompose
|
|
298
107
|
def raise_on_save_error = raise ActiveRecord::RecordNotSaved.new(raise_on_save_error_message, self)
|
299
108
|
|
300
109
|
def raise_on_save_error_message = 'Failed to save the model.'
|
301
|
-
|
302
|
-
# steep:ignore:start
|
303
|
-
def deprecator
|
304
|
-
if ActiveRecord.respond_to?(:deprecator)
|
305
|
-
ActiveRecord.deprecator
|
306
|
-
else # for rails 7.0.x or lower
|
307
|
-
ActiveSupport::Deprecation
|
308
|
-
end
|
309
|
-
end
|
310
|
-
# steep:ignore:end
|
311
110
|
end
|
312
111
|
end
|
@@ -7,15 +7,3 @@ require_relative 'active_record_compose/model'
|
|
7
7
|
|
8
8
|
module ActiveRecordCompose
|
9
9
|
end
|
10
|
-
|
11
|
-
if ActiveRecordCompose::VERSION == '0.8.1'
|
12
|
-
unless ENV['ACTIVE_RECORD_COMPOSE_SILENCE_DEPRECATION'] # rubocop:disable Style/SoleNestedConditional
|
13
|
-
warn <<~WARN
|
14
|
-
|
15
|
-
[DEPRECATION] You are using active_record_compose version 0.8.1, which is deprecated.
|
16
|
-
Please upgrade to the latest version.
|
17
|
-
See: https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md
|
18
|
-
|
19
|
-
WARN
|
20
|
-
end
|
21
|
-
end
|
@@ -24,7 +24,7 @@ module ActiveRecordCompose
|
|
24
24
|
def delegated_attributes: () -> Array[String]
|
25
25
|
|
26
26
|
module ClassMethods : Module
|
27
|
-
def delegate_attribute: (*untyped methods, to: untyped, ?allow_nil: untyped
|
27
|
+
def delegate_attribute: (*untyped methods, to: untyped, ?allow_nil: untyped?) -> untyped
|
28
28
|
def delegated_attributes: () -> Array[String]
|
29
29
|
def delegated_attributes=: (Array[String]) -> untyped
|
30
30
|
end
|
@@ -69,10 +69,7 @@ module ActiveRecordCompose
|
|
69
69
|
def self.after_commit: (*callback[instance], ?if: condition[instance], ?unless: condition[instance], **untyped) ?{ () [self: instance] -> void } -> void
|
70
70
|
def self.after_rollback: (*callback[instance], ?if: condition[instance], ?unless: condition[instance], **untyped) ?{ () [self: instance] -> void } -> void
|
71
71
|
|
72
|
-
def self.
|
73
|
-
def self.persisted_flag_callback_control=: (boolish) -> untyped
|
74
|
-
|
75
|
-
def self.delegate_attribute: (*untyped methods, to: untyped, ?allow_nil: untyped?, ?private: untyped?) -> untyped
|
72
|
+
def self.delegate_attribute: (*untyped methods, to: untyped, ?allow_nil: untyped?) -> untyped
|
76
73
|
def self.connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
|
77
74
|
def self.lease_connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
|
78
75
|
def self.with_connection: [T] () { () -> T } -> T
|
@@ -88,8 +85,8 @@ module ActiveRecordCompose
|
|
88
85
|
|
89
86
|
private
|
90
87
|
def models: -> ComposedCollection
|
91
|
-
def with_callbacks:
|
92
|
-
def callback_context:
|
88
|
+
def with_callbacks: { () -> bool } -> bool
|
89
|
+
def callback_context: -> (:create | :update)
|
93
90
|
def validate_models: -> void
|
94
91
|
def save_models: (bang: bool) -> bool
|
95
92
|
def raise_validation_error: -> bot
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_compose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hamajyotan
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-16 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activerecord
|
@@ -16,9 +16,6 @@ dependencies:
|
|
16
16
|
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
18
|
version: '7.0'
|
19
|
-
- - "<"
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '8.1'
|
22
19
|
type: :runtime
|
23
20
|
prerelease: false
|
24
21
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,9 +23,6 @@ dependencies:
|
|
26
23
|
- - ">="
|
27
24
|
- !ruby/object:Gem::Version
|
28
25
|
version: '7.0'
|
29
|
-
- - "<"
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: '8.1'
|
32
26
|
description: activemodel form object pattern. it embraces multiple AR models and provides
|
33
27
|
a transparent interface as if they were a single model.
|
34
28
|
email:
|
@@ -42,7 +36,6 @@ files:
|
|
42
36
|
- CODE_OF_CONDUCT.md
|
43
37
|
- LICENSE.txt
|
44
38
|
- README.md
|
45
|
-
- UPGRADE.md
|
46
39
|
- lib/active_record_compose.rb
|
47
40
|
- lib/active_record_compose/composed_collection.rb
|
48
41
|
- lib/active_record_compose/delegate_attribute.rb
|
@@ -59,17 +52,8 @@ metadata:
|
|
59
52
|
homepage_uri: https://github.com/hamajyotan/active_record_compose
|
60
53
|
source_code_uri: https://github.com/hamajyotan/active_record_compose
|
61
54
|
changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
|
62
|
-
documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.
|
55
|
+
documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.9.0
|
63
56
|
rubygems_mfa_required: 'true'
|
64
|
-
post_install_message: |2+
|
65
|
-
|
66
|
-
Notice: This version (0.8.1) is deprecated.
|
67
|
-
|
68
|
-
Please upgrade to the latest version of `active_record_compose` as soon as possible.
|
69
|
-
Future releases will not support this version.
|
70
|
-
|
71
|
-
See https://github.com/hamajyotan/active_record_compose/blob/v0.8.1/UPGRADE.md for migration steps.
|
72
|
-
|
73
57
|
rdoc_options: []
|
74
58
|
require_paths:
|
75
59
|
- lib
|
@@ -88,4 +72,3 @@ rubygems_version: 3.6.2
|
|
88
72
|
specification_version: 4
|
89
73
|
summary: activemodel form object pattern
|
90
74
|
test_files: []
|
91
|
-
...
|
data/UPGRADE.md
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
# Migration Guide: `active_record_compose` 0.8.x to 0.9.0+
|
2
|
-
|
3
|
-
⚠️ **Breaking Change**
|
4
|
-
|
5
|
-
This guide explains how to migrate from version **0.8.x** to **0.9.0 or later**, assuming that your codebase includes:
|
6
|
-
|
7
|
-
```ruby
|
8
|
-
self.persisted_flag_callback_control = false
|
9
|
-
```
|
10
|
-
|
11
|
-
This setting was officially **deprecated** in 0.9.0 and is **no longer supported**. Migration is required to adopt the current default behavior.
|
12
|
-
|
13
|
-
## Background
|
14
|
-
|
15
|
-
In version **0.7.x**, the default value of `persisted_flag_callback_control` was `false`.
|
16
|
-
|
17
|
-
In **0.8.x**, the default was changed to `true`.
|
18
|
-
If you are still using `false` in your models, it means you have **explicitly overridden the default**, likely to preserve backward-compatible behavior.
|
19
|
-
|
20
|
-
This guide helps you safely migrate to the new behavior while preserving intended callback semantics.
|
21
|
-
|
22
|
-
## Goal of the Migration
|
23
|
-
|
24
|
-
- Remove any use of `persisted_flag_callback_control = false`
|
25
|
-
- Adjust callback definitions to align with the semantics of `#persisted?`
|
26
|
-
|
27
|
-
## Step 1 – Remove Deprecated Flag
|
28
|
-
|
29
|
-
Find and remove all instances of:
|
30
|
-
|
31
|
-
```diff
|
32
|
-
-self.persisted_flag_callback_control = false
|
33
|
-
```
|
34
|
-
|
35
|
-
## Step 2 – Understand Callback Behavior Changes
|
36
|
-
|
37
|
-
With `persisted_flag_callback_control = true`, whether a callback is fired depends on the return value of `#persisted?`, not the method used (`create` or `update`).
|
38
|
-
|
39
|
-
### When saving with `#update`:
|
40
|
-
|
41
|
-
If `persisted?` returns `false`, then:
|
42
|
-
|
43
|
-
- `before_update`
|
44
|
-
- `after_update`
|
45
|
-
- `around_update`
|
46
|
-
|
47
|
-
will **not** be triggered.
|
48
|
-
|
49
|
-
✅ Recommended fix:
|
50
|
-
|
51
|
-
If you don’t differentiate between creation and update phases, switch to `*_save` callbacks:
|
52
|
-
|
53
|
-
```diff
|
54
|
-
- before_update :track_change
|
55
|
-
+ before_save :track_change
|
56
|
-
```
|
57
|
-
|
58
|
-
### When saving with `#create`:
|
59
|
-
|
60
|
-
If `persisted?` returns `true`, then:
|
61
|
-
|
62
|
-
- `before_create`
|
63
|
-
- `after_create`
|
64
|
-
- `around_create`
|
65
|
-
|
66
|
-
will **not** be triggered.
|
67
|
-
|
68
|
-
✅ Recommended fix:
|
69
|
-
|
70
|
-
Again, prefer `*_save` if you're using shared logic across creation and update:
|
71
|
-
|
72
|
-
```diff
|
73
|
-
- after_create :send_notification
|
74
|
-
+ after_save :send_notification
|
75
|
-
```
|
76
|
-
|
77
|
-
## Step 3 – Override `#persisted?` if Needed
|
78
|
-
|
79
|
-
If your composed model wraps an ActiveRecord instance and delegates its persistence logic, be sure to override `#persisted?` to reflect the correct state:
|
80
|
-
|
81
|
-
```ruby
|
82
|
-
class Foo < ActiveRecordCompose::Model
|
83
|
-
def initialize(bar = Bar.new)
|
84
|
-
super()
|
85
|
-
@bar = bar
|
86
|
-
end
|
87
|
-
|
88
|
-
def persisted? = bar.persisted?
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
attr_reader :bar
|
93
|
-
end
|
94
|
-
```
|
95
|
-
|
96
|
-
## Migration Checklist ✅
|
97
|
-
|
98
|
-
- [ ] All models now `persisted_flag_callback_control` omit it entirely
|
99
|
-
- [ ] All callback definitions have been reviewed and updated
|
100
|
-
- [ ] Any `*_create` or `*_update` callbacks have been replaced with `*_save` where applicable
|
101
|
-
- [ ] `#persisted?` is correctly overridden where needed
|
102
|
-
- [ ] All tests pass and expected callbacks are fired
|
103
|
-
|
104
|
-
## Why This Change?
|
105
|
-
|
106
|
-
By aligning callback behavior with `persisted?`, you gain:
|
107
|
-
|
108
|
-
- Clearer intent and semantics
|
109
|
-
- More accurate behavior when composing or wrapping persisted models
|
110
|
-
- Improved compatibility with Rails conventions
|
111
|
-
- Less surprising callback triggering
|
112
|
-
|
113
|
-
If you have questions or run into edge cases, feel free to [open an issue](https://github.com/hamajyotan/active_record_compose/issues) or start a discussion.
|