active_record_compose 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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: