active_record_compose 0.7.0 → 0.8.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: ab0bb2d4ff8813ad8fb9a4830c2b1d3887aaa29702f11561c9c8624719a5082f
4
- data.tar.gz: a3fcfb870aaf5a0825a218556423cc1af16644b41ec22f0b4d656cb42cd33790
3
+ metadata.gz: 690ecf032eb0a4c59c97394702c838142a4d519145f72e58f9a381d956cad5ce
4
+ data.tar.gz: 7133a2f5defa0d1c97dac41b207936512f6d5375e8f534ea77dc6c13c3f61dde
5
5
  SHA512:
6
- metadata.gz: d5a1ea42bd83a986437faac38b2543ee48aff7f2003afa6267a7adcd325db1bbb0506f4f1f25e2aaa13b733df7956ebd820627821f19101fc36dd4f046a51c43
7
- data.tar.gz: 4a9cc98fddbcf1068720387207469cb527b96e536a9f109a6174b5a439daa383f54a1625e916c731d01883cf360c6e01281858a238796b5cb64b92665c2405c3
6
+ metadata.gz: 2680382210cf6eb2f8371cca7e656f8b00211361f00bf9aed7d2ee4f006a816eee6298a917e48c67d5b4f6149545f2ebb3e67bd5905946279c9e203e9e378d82
7
+ data.tar.gz: 63aa5b0a8abcbcd59eb81aadadf4c8207622988ad417b09d2e8f977615ed8726233ae8f257f8d8847e16e38f400955e0bda1d9340f9c7733f06ea8d76fa4854a
data/.rubocop.yml CHANGED
@@ -21,6 +21,9 @@ Style/DoubleNegation:
21
21
  Style/NumericPredicate:
22
22
  Enabled: false
23
23
 
24
+ Style/OptionalBooleanParameter:
25
+ Enabled: false
26
+
24
27
  Style/StringLiterals:
25
28
  Enabled: true
26
29
 
@@ -48,6 +51,9 @@ Layout/LeadingCommentSpace:
48
51
  Layout/LineLength:
49
52
  Max: 120
50
53
 
54
+ Lint/UselessMethodDefinition:
55
+ Enabled: false
56
+
51
57
  Metrics/AbcSize:
52
58
  Enabled: false
53
59
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.8.0] - 2025-02-22
4
+
5
+ - changed `persisted_flag_callback_control` default from `false` to `true`.
6
+ - adjusted to save errors as soon as an invalid is found.
7
+ - drop support rails 6.1.x.
8
+
3
9
  ## [0.7.0] - 2025-02-12
4
10
 
5
11
  - rename ActiveRecordCompose::InnerModel to ActiveRecordCompose::WrappedModel
data/README.md CHANGED
@@ -15,7 +15,7 @@ activemodel (activerecord) form object pattern. it embraces multiple AR models a
15
15
  - [I18n](#i18n)
16
16
  - [Advanced Usage](#advanced-usage)
17
17
  - [`destroy` option](#destroy-option)
18
- - [Callback ordering by `#save`, `#create` and `#update`](#callback-ordering-by-save-create-and-update)
18
+ - [Callback ordering by `#persisted?`](#callback-ordering-by-persisted)
19
19
  - [Links](#links)
20
20
  - [Development](#development)
21
21
  - [Contributing](#contributing)
@@ -284,52 +284,15 @@ class AccountRegistration < ActiveRecordCompose::Model
284
284
  end
285
285
  ```
286
286
 
287
- ### Callback ordering by `#save`, `#create` and `#update`.
287
+ ### Callback ordering by `#persisted?`
288
288
 
289
289
  The behavior of `(before|after|around)_create` and `(before|after|around)_update` hooks depends on
290
290
  the state of the `persisted_flag_callback_control` setting.
291
-
292
- When `persisted_flag_callback_control` is set to false,
293
- the execution of `#create`, `#update`, or `#save` determines which callbacks will be triggered.
294
- Currently, the default value is `false`, but it will no longer be supported in the future.
295
-
296
- ```ruby
297
- class ComposedModel < ActiveRecordCompose::Model
298
- self.persisted_flag_callback_control = false # Currently defaults to false, but will no longer be supported in the future.
299
-
300
- # ...
301
-
302
- before_save { puts 'before_save called!' }
303
- before_create { puts 'before_create called!' }
304
- before_update { puts 'before_update called!' }
305
- after_save { puts 'after_save called!' }
306
- after_create { puts 'after_create called!' }
307
- after_update { puts 'after_update called!' }
308
- end
309
- ```
310
-
311
- ```ruby
312
- model = ComposedModel.new
313
-
314
- model.save
315
- # before_save called!
316
- # after_save called!
317
-
318
- model.create
319
- # before_save called!
320
- # before_create called!
321
- # after_create called!
322
- # after_save called!
323
-
324
- model.update
325
- # before_save called!
326
- # before_update called!
327
- # after_update called!
328
- # after_save called!
329
- ```
291
+ default value is `true`, behavior when set to `false` will be removed in the next release.
330
292
 
331
293
  When `persisted_flag_callback_control` is set to `true`, it behaves almost like callback control in ActiveRecord.
332
- This behavior will be the default in the future.
294
+ Depending on the evaluation result of `#persisted?`,
295
+ either the create-related callbacks or the update-related callbacks will be triggered.
333
296
 
334
297
  ```ruby
335
298
  class ComposedModel < ActiveRecordCompose::Model
@@ -382,10 +345,43 @@ model.save # or `model.update` (the same callbacks will be triggered in all case
382
345
  # after_save called!
383
346
  ```
384
347
 
385
- When `persisted_flag_callback_control` is `true`, `#create` is not supported.
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
+ ```
386
366
 
387
367
  ```ruby
388
- model.create # => raises RuntimeError
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!
389
385
  ```
390
386
 
391
387
  ## Links
@@ -16,7 +16,7 @@ module ActiveRecordCompose
16
16
  include ActiveRecordCompose::TransactionSupport
17
17
 
18
18
  # This flag controls the callback sequence for models.
19
- # The current default value is `false`, but support for `false` is planned to be discontinued in the future.
19
+ # The current default value is `true`, behavior when set to `false` will be removed in the next release.
20
20
  #
21
21
  # When `persisted_flag_callback_control` is set to `true`,
22
22
  # the occurrence of callbacks depends on the evaluation result of `#persisted?`.
@@ -53,7 +53,7 @@ module ActiveRecordCompose
53
53
  # * after_create
54
54
  # * after_save
55
55
  #
56
- class_attribute :persisted_flag_callback_control, instance_accessor: false, default: false
56
+ class_attribute :persisted_flag_callback_control, instance_accessor: false, default: true
57
57
 
58
58
  define_model_callbacks :save
59
59
  define_model_callbacks :create
@@ -78,6 +78,13 @@ module ActiveRecordCompose
78
78
  if self.class.persisted_flag_callback_control
79
79
  with_callbacks { save_models(bang: false) }
80
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
+ )
87
+ # steep:ignore:end
81
88
  run_callbacks(:save) { save_models(bang: false) }
82
89
  end
83
90
  rescue ActiveRecord::RecordInvalid
@@ -97,6 +104,13 @@ module ActiveRecordCompose
97
104
  if self.class.persisted_flag_callback_control
98
105
  with_callbacks { save_models(bang: true) }
99
106
  else
107
+ # steep:ignore:start
108
+ deprecator.warn(
109
+ 'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
110
+ 'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
111
+ '(Alternatively, exclude statements that set `false`)',
112
+ )
113
+ # steep:ignore:end
100
114
  run_callbacks(:save) { save_models(bang: true) }
101
115
  end
102
116
  end || raise_on_save_error
@@ -127,11 +141,20 @@ module ActiveRecordCompose
127
141
  # # after_create called!
128
142
  # # after_save called!
129
143
  #
144
+ # @deprecated
130
145
  def create(attributes = {})
131
146
  if self.class.persisted_flag_callback_control
132
147
  raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
133
148
  end
134
149
 
150
+ # steep:ignore:start
151
+ deprecator.warn(
152
+ 'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
153
+ 'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
154
+ '(Alternatively, exclude statements that set `false`)',
155
+ )
156
+ # steep:ignore:end
157
+
135
158
  assign_attributes(attributes)
136
159
  return false if invalid?
137
160
 
@@ -144,11 +167,20 @@ module ActiveRecordCompose
144
167
 
145
168
  # Behavior is same to `#create`, but raises an exception prematurely on failure.
146
169
  #
170
+ # @deprecated
147
171
  def create!(attributes = {})
148
172
  if self.class.persisted_flag_callback_control
149
173
  raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
150
174
  end
151
175
 
176
+ # steep:ignore:start
177
+ deprecator.warn(
178
+ 'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
179
+ 'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
180
+ '(Alternatively, exclude statements that set `false`)',
181
+ )
182
+ # steep:ignore:end
183
+
152
184
  assign_attributes(attributes)
153
185
  valid? || raise_validation_error
154
186
 
@@ -190,6 +222,13 @@ module ActiveRecordCompose
190
222
  if self.class.persisted_flag_callback_control
191
223
  with_callbacks { save_models(bang: false) }
192
224
  else
225
+ # steep:ignore:start
226
+ deprecator.warn(
227
+ 'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
228
+ 'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
229
+ '(Alternatively, exclude statements that set `false`)',
230
+ )
231
+ # steep:ignore:end
193
232
  with_callbacks(context: :update) { save_models(bang: false) }
194
233
  end
195
234
  rescue ActiveRecord::RecordInvalid
@@ -207,22 +246,41 @@ module ActiveRecordCompose
207
246
  if self.class.persisted_flag_callback_control
208
247
  with_callbacks { save_models(bang: true) }
209
248
  else
249
+ # steep:ignore:start
250
+ deprecator.warn(
251
+ 'The behavior with `persisted_flag_callback_control` set to `false` will be removed in 0.9.0. ' \
252
+ 'Use `self.persisted_flag_callback_control = true` set to `true`. ' \
253
+ '(Alternatively, exclude statements that set `false`)',
254
+ )
255
+ # steep:ignore:end
210
256
  with_callbacks(context: :update) { save_models(bang: true) }
211
257
  end
212
258
  end || raise_on_save_error
213
259
  end
214
260
 
261
+ # Returns true if model is persisted.
262
+ #
263
+ # By overriding this definition, you can control the callbacks that are triggered when a save is made.
264
+ # For example, returning false will trigger before_create, around_create and after_create,
265
+ # and returning true will trigger before_update, around_update and after_update.
266
+ #
267
+ # @return [Boolean] returns true if model is persisted.
268
+ def persisted? = super
269
+
215
270
  private
216
271
 
217
272
  def models = @__models ||= ActiveRecordCompose::ComposedCollection.new(self)
218
273
 
219
274
  def validate_models
220
- models.__wrapped_models.select { _1.invalid? }.each { errors.merge!(_1) }
275
+ models.__wrapped_models.lazy.select { _1.invalid? }.each { errors.merge!(_1) }
221
276
  end
222
277
 
223
278
  def with_callbacks(context: nil, &block)
224
- context ||= persisted? ? :update : :create
225
- run_callbacks(:save) { run_callbacks(context, &block) }
279
+ run_callbacks(:save) { run_callbacks(callback_context(context:), &block) }
280
+ end
281
+
282
+ def callback_context(context: nil)
283
+ context || (persisted? ? :update : :create)
226
284
  end
227
285
 
228
286
  def save_models(bang:)
@@ -234,5 +292,13 @@ module ActiveRecordCompose
234
292
  def raise_on_save_error = raise ActiveRecord::RecordNotSaved.new(raise_on_save_error_message, self)
235
293
 
236
294
  def raise_on_save_error_message = 'Failed to save the model.'
295
+
296
+ def deprecator
297
+ if ActiveRecord.respond_to?(:deprecator)
298
+ ActiveRecord.deprecator # steep:ignore
299
+ else # for rails 7.0.x or lower
300
+ ActiveSupport::Deprecation
301
+ end
302
+ end
237
303
  end
238
304
  end
@@ -28,6 +28,6 @@ module ActiveRecordCompose
28
28
  def id = nil
29
29
 
30
30
  def trigger_transactional_callbacks? = true
31
- def restore_transaction_record_state(_force_restore_state = false) = nil # rubocop:disable Style/OptionalBooleanParameter
31
+ def restore_transaction_record_state(_force_restore_state = false) = nil
32
32
  end
33
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -89,6 +89,7 @@ module ActiveRecordCompose
89
89
  private
90
90
  def models: -> ComposedCollection
91
91
  def with_callbacks: (?context: (nil | :create | :update)) { () -> bool } -> bool
92
+ def callback_context: (?context: (nil | :create | :update)) -> (:create | :update)
92
93
  def validate_models: -> void
93
94
  def save_models: (bang: bool) -> bool
94
95
  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.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamajyotan
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-12 00:00:00.000000000 Z
10
+ date: 2025-02-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activerecord
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '6.1'
18
+ version: '7.0'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '6.1'
25
+ version: '7.0'
26
26
  description: activemodel form object pattern. it embraces multiple AR models and provides
27
27
  a transparent interface as if they were a single model.
28
28
  email:
@@ -52,7 +52,7 @@ metadata:
52
52
  homepage_uri: https://github.com/hamajyotan/active_record_compose
53
53
  source_code_uri: https://github.com/hamajyotan/active_record_compose
54
54
  changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
55
- documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.7.0
55
+ documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.8.0
56
56
  rubygems_mfa_required: 'true'
57
57
  rdoc_options: []
58
58
  require_paths: