active_record_compose 0.6.3 → 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: 6a3d2a1c6e4aac0bc387a6e0d9ba2917dafeacec4d46b2ad617d54e45ff9786f
4
- data.tar.gz: d71b88c9b069eca62e49d2e5ff25c447a5e70e741d29b76f572c5a21b4994a4b
3
+ metadata.gz: 690ecf032eb0a4c59c97394702c838142a4d519145f72e58f9a381d956cad5ce
4
+ data.tar.gz: 7133a2f5defa0d1c97dac41b207936512f6d5375e8f534ea77dc6c13c3f61dde
5
5
  SHA512:
6
- metadata.gz: 3579fdc36270eaaa2f9f253b247aabc5bc4aa6547df5511e81158ebbf3277b37dbbaa3e4d4376fff5c9ac0066cebbf0207db993cd20b4c8b159a6f3069ae24f1
7
- data.tar.gz: 4f2e98a4158a5c19c13f5bc5d83276c7071ece19b2c969d73c24cce47231c9f272fb32620d5a31748e2bd060d72733bcd28be3d4d3eb6c1e9c8ded1bb9db0340
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,6 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.6.2] - 2025-01-31
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
+
9
+ ## [0.7.0] - 2025-02-12
10
+
11
+ - rename ActiveRecordCompose::InnerModel to ActiveRecordCompose::WrappedModel
12
+ - rename ActiveRecordCompose::InnerModelCollection to ActiveRecordCompose::ComposedCollection
13
+ - A new callback control flag, `persisted_flag_callback_control`, has been defined.
14
+ Currently, the default value is false, which does not change the existing behavior, but it will be deprecated in the future.
15
+ When the flag is set to true, the behavior will be almost the same as the callback sequence in ActiveRecord.
16
+ (https://github.com/hamajyotan/active_record_compose/issues/11)
17
+
18
+ ## [0.6.3] - 2025-01-31
4
19
 
5
20
  - fix: type error in `ActiveRecordCompose::Model` subclass definitions.
6
21
  - fixed type errors in subclass callback definitions, etc.
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,15 +284,75 @@ 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
- Sometimes, multiple AR objects are passed to the models in the arguments.
290
- It is not strictly possible to distinguish between create and update operations, regardless of the state of `#persisted?`.
291
- Therefore, control measures such as separating callbacks with `after_create` and `after_update` based on the `#persisted?` of AR objects are left to the discretion of the user,
292
- rather than being determined by the state of the AR objects themselves.
289
+ The behavior of `(before|after|around)_create` and `(before|after|around)_update` hooks depends on
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?`,
295
+ either the create-related callbacks or the update-related callbacks will be triggered.
293
296
 
294
297
  ```ruby
295
298
  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
+ # ...
302
+
303
+ before_save { puts 'before_save called!' }
304
+ before_create { puts 'before_create called!' }
305
+ before_update { puts 'before_update called!' }
306
+ after_save { puts 'after_save called!' }
307
+ after_create { puts 'after_create called!' }
308
+ after_update { puts 'after_update called!' }
309
+
310
+ def persisted?
311
+ # Override and return a boolish value depending on the state of the inner model.
312
+ # For example, it could be transferred to the primary model to be manipulated.
313
+ #
314
+ # # ex.)
315
+ # def persisted? = the_model.persisted?
316
+ #
317
+ true
318
+ end
319
+ end
320
+ ```
321
+
322
+ ```ruby
323
+ # when `model.persisted?` returns `true`
324
+
325
+ model = ComposedModel.new
326
+
327
+ model.save # or `model.update` (the same callbacks will be triggered in all cases).
328
+
329
+ # before_save called!
330
+ # before_update called! # when persisted? is false, before_create hook is fired here instead.
331
+ # after_update called! # when persisted? is false, after_create hook is fired here instead.
332
+ # after_save called!
333
+ ```
334
+
335
+ ```ruby
336
+ # when `model.persisted?` returns `false`
337
+
338
+ model = ComposedModel.new
339
+
340
+ model.save # or `model.update` (the same callbacks will be triggered in all cases).
341
+
342
+ # before_save called!
343
+ # before_create called!
344
+ # after_create called!
345
+ # after_save called!
346
+ ```
347
+
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
+
296
356
  # ...
297
357
 
298
358
  before_save { puts 'before_save called!' }
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record_compose/inner_model'
3
+ require 'active_record_compose/wrapped_model'
4
4
 
5
5
  module ActiveRecordCompose
6
- using InnerModel::PackagePrivate
6
+ using WrappedModel::PackagePrivate
7
7
 
8
- class InnerModelCollection
8
+ class ComposedCollection
9
9
  include Enumerable
10
10
 
11
11
  def initialize(owner)
@@ -79,30 +79,25 @@ module ActiveRecordCompose
79
79
  attr_reader :owner, :models
80
80
 
81
81
  def wrap(model, destroy: false, if: nil)
82
- if model.is_a?(ActiveRecordCompose::InnerModel)
83
- # @type var model: ActiveRecordCompose::InnerModel
84
- model
85
- else
86
- if destroy.is_a?(Symbol)
87
- method = destroy
88
- destroy = -> { owner.__send__(method) }
89
- end
90
- if_option = binding.local_variable_get(:if)
91
- if if_option.is_a?(Symbol)
92
- method = if_option
93
- if_option = -> { owner.__send__(method) }
94
- end
95
- ActiveRecordCompose::InnerModel.new(model, destroy:, if: if_option)
82
+ if destroy.is_a?(Symbol)
83
+ method = destroy
84
+ destroy = -> { owner.__send__(method) }
96
85
  end
86
+ if_option = binding.local_variable_get(:if)
87
+ if if_option.is_a?(Symbol)
88
+ method = if_option
89
+ if_option = -> { owner.__send__(method) }
90
+ end
91
+ ActiveRecordCompose::WrappedModel.new(model, destroy:, if: if_option)
97
92
  end
98
93
 
99
94
  # @private
100
95
  module PackagePrivate
101
- refine InnerModelCollection do
96
+ refine ComposedCollection do
102
97
  # Returns array of wrapped model instance.
103
98
  #
104
99
  # @private
105
- # @return [Array[InnerModel] array of wrapped model instance.
100
+ # @return [Array[WrappedModel]] array of wrapped model instance.
106
101
  def __wrapped_models = models.reject { _1.ignore? }.select { _1.__raw_model }
107
102
  end
108
103
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_record_compose/composed_collection'
3
4
  require 'active_record_compose/delegate_attribute'
4
- require 'active_record_compose/inner_model_collection'
5
5
  require 'active_record_compose/transaction_support'
6
6
 
7
7
  module ActiveRecordCompose
8
- using InnerModelCollection::PackagePrivate
8
+ using ComposedCollection::PackagePrivate
9
9
 
10
10
  class Model
11
11
  include ActiveModel::Model
@@ -15,6 +15,46 @@ 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
+
18
58
  define_model_callbacks :save
19
59
  define_model_callbacks :create
20
60
  define_model_callbacks :update
@@ -35,7 +75,18 @@ module ActiveRecordCompose
35
75
  return false if invalid?
36
76
 
37
77
  with_transaction_returning_status do
38
- run_callbacks(:save) { save_models(bang: false) }
78
+ if self.class.persisted_flag_callback_control
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
+ )
87
+ # steep:ignore:end
88
+ run_callbacks(:save) { save_models(bang: false) }
89
+ end
39
90
  rescue ActiveRecord::RecordInvalid
40
91
  false
41
92
  end
@@ -50,7 +101,18 @@ module ActiveRecordCompose
50
101
  valid? || raise_validation_error
51
102
 
52
103
  with_transaction_returning_status do
53
- run_callbacks(:save) { save_models(bang: true) }
104
+ if self.class.persisted_flag_callback_control
105
+ with_callbacks { save_models(bang: true) }
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
114
+ run_callbacks(:save) { save_models(bang: true) }
115
+ end
54
116
  end || raise_on_save_error
55
117
  end
56
118
 
@@ -79,12 +141,25 @@ module ActiveRecordCompose
79
141
  # # after_create called!
80
142
  # # after_save called!
81
143
  #
144
+ # @deprecated
82
145
  def create(attributes = {})
146
+ if self.class.persisted_flag_callback_control
147
+ raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
148
+ end
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
+
83
158
  assign_attributes(attributes)
84
159
  return false if invalid?
85
160
 
86
161
  with_transaction_returning_status do
87
- run_callbacks(:save) { run_callbacks(:create) { save_models(bang: false) } }
162
+ with_callbacks(context: :create) { save_models(bang: false) }
88
163
  rescue ActiveRecord::RecordInvalid
89
164
  false
90
165
  end
@@ -92,12 +167,25 @@ module ActiveRecordCompose
92
167
 
93
168
  # Behavior is same to `#create`, but raises an exception prematurely on failure.
94
169
  #
170
+ # @deprecated
95
171
  def create!(attributes = {})
172
+ if self.class.persisted_flag_callback_control
173
+ raise '`#create` cannot be called. The context for creation or update is determined by the `#persisted` flag.'
174
+ end
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
+
96
184
  assign_attributes(attributes)
97
185
  valid? || raise_validation_error
98
186
 
99
187
  with_transaction_returning_status do
100
- run_callbacks(:save) { run_callbacks(:create) { save_models(bang: true) } }
188
+ with_callbacks(context: :create) { save_models(bang: true) }
101
189
  end || raise_on_save_error
102
190
  end
103
191
 
@@ -131,7 +219,18 @@ module ActiveRecordCompose
131
219
  return false if invalid?
132
220
 
133
221
  with_transaction_returning_status do
134
- run_callbacks(:save) { run_callbacks(:update) { save_models(bang: false) } }
222
+ if self.class.persisted_flag_callback_control
223
+ with_callbacks { save_models(bang: false) }
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
232
+ with_callbacks(context: :update) { save_models(bang: false) }
233
+ end
135
234
  rescue ActiveRecord::RecordInvalid
136
235
  false
137
236
  end
@@ -144,22 +243,48 @@ module ActiveRecordCompose
144
243
  valid? || raise_validation_error
145
244
 
146
245
  with_transaction_returning_status do
147
- run_callbacks(:save) { run_callbacks(:update) { save_models(bang: true) } }
246
+ if self.class.persisted_flag_callback_control
247
+ with_callbacks { save_models(bang: true) }
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
256
+ with_callbacks(context: :update) { save_models(bang: true) }
257
+ end
148
258
  end || raise_on_save_error
149
259
  end
150
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
+
151
270
  private
152
271
 
153
- def models = @__models ||= ActiveRecordCompose::InnerModelCollection.new(self)
272
+ def models = @__models ||= ActiveRecordCompose::ComposedCollection.new(self)
154
273
 
155
274
  def validate_models
156
- wms = models.__wrapped_models
157
- wms.select { _1.invalid? }.each { errors.merge!(_1) }
275
+ models.__wrapped_models.lazy.select { _1.invalid? }.each { errors.merge!(_1) }
276
+ end
277
+
278
+ def with_callbacks(context: nil, &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)
158
284
  end
159
285
 
160
286
  def save_models(bang:)
161
- wms = models.__wrapped_models
162
- wms.all? { bang ? _1.save! : _1.save }
287
+ models.__wrapped_models.all? { bang ? _1.save! : _1.save }
163
288
  end
164
289
 
165
290
  def raise_validation_error = raise ActiveRecord::RecordInvalid, self
@@ -167,5 +292,13 @@ module ActiveRecordCompose
167
292
  def raise_on_save_error = raise ActiveRecord::RecordNotSaved.new(raise_on_save_error_message, self)
168
293
 
169
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
170
303
  end
171
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.6.3'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -3,7 +3,7 @@
3
3
  require 'active_support/core_ext/object'
4
4
 
5
5
  module ActiveRecordCompose
6
- class InnerModel
6
+ class WrappedModel
7
7
  # @param model [Object] the model instance.
8
8
  # @param destroy [Boolean] given true, destroy model.
9
9
  # @param destroy [Proc] when proc returning true, destroy model.
@@ -17,7 +17,7 @@ module ActiveRecordCompose
17
17
  delegate :errors, to: :model
18
18
 
19
19
  # Determines whether to save or delete the target object.
20
- # Depends on the `destroy` value of the InnerModel object initialization option.
20
+ # Depends on the `destroy` value of the WrappedModel object initialization option.
21
21
  #
22
22
  # On the other hand, there are values `mark_for_destruction` and `marked_for_destruction?` in ActiveRecord.
23
23
  # However, these values are not substituted here.
@@ -118,7 +118,7 @@ module ActiveRecordCompose
118
118
 
119
119
  # @private
120
120
  module PackagePrivate
121
- refine InnerModel do
121
+ refine WrappedModel do
122
122
  # @private
123
123
  # Returns a model instance of raw, but it should
124
124
  # be noted that application developers are not expected to use this interface.
@@ -1,4 +1,22 @@
1
1
  module ActiveRecordCompose
2
+ class ComposedCollection
3
+ def initialize: (Model) -> void
4
+
5
+ private
6
+ attr_reader owner: Model
7
+ attr_reader models: Array[WrappedModel]
8
+ def wrap: (ar_like, ?destroy: (bool | Symbol | destroy_context_type), ?if: (nil | Symbol | condition_type)) -> WrappedModel
9
+
10
+ module PackagePrivate
11
+ def __wrapped_models: () -> Array[WrappedModel]
12
+
13
+ private
14
+ def models: () -> Array[WrappedModel]
15
+ end
16
+
17
+ include PackagePrivate
18
+ end
19
+
2
20
  module DelegateAttribute : ActiveModel::Attributes
3
21
  extend ActiveSupport::Concern
4
22
 
@@ -12,25 +30,31 @@ module ActiveRecordCompose
12
30
  end
13
31
  end
14
32
 
15
- class InnerModelCollection
16
- def initialize: (Model) -> void
33
+ class Model
34
+ include DelegateAttribute
35
+ extend DelegateAttribute::ClassMethods
36
+ include TransactionSupport
37
+ extend TransactionSupport::ClassMethods
17
38
 
18
- private
19
- attr_reader owner: Model
20
- attr_reader models: Array[InnerModel]
21
- def wrap: (ar_like | InnerModel, ?destroy: (bool | Symbol | destroy_context_type), ?if: (nil | Symbol | condition_type)) -> InnerModel
39
+ @__models: ComposedCollection
40
+ end
22
41
 
23
- module PackagePrivate
24
- def __wrapped_models: () -> Array[InnerModel]
42
+ module TransactionSupport
43
+ include ActiveRecord::Transactions
44
+
45
+ def id: -> untyped
46
+
47
+ module ClassMethods
48
+ def connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
49
+ def lease_connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
50
+ def with_connection: [T] () { () -> T } -> T
25
51
 
26
52
  private
27
- def models: () -> Array[InnerModel]
53
+ def ar_class: -> singleton(ActiveRecord::Base)
28
54
  end
29
-
30
- include PackagePrivate
31
55
  end
32
56
 
33
- class InnerModel
57
+ class WrappedModel
34
58
  def initialize: (ar_like, ?destroy: (bool | destroy_context_type), ?if: (nil | condition_type)) -> void
35
59
  def destroy_context?: -> bool
36
60
  def ignore?: -> bool
@@ -55,28 +79,4 @@ module ActiveRecordCompose
55
79
 
56
80
  include PackagePrivate
57
81
  end
58
-
59
- class Model
60
- include DelegateAttribute
61
- extend DelegateAttribute::ClassMethods
62
- include TransactionSupport
63
- extend TransactionSupport::ClassMethods
64
-
65
- @__models: InnerModelCollection
66
- end
67
-
68
- module TransactionSupport
69
- include ActiveRecord::Transactions
70
-
71
- def id: -> untyped
72
-
73
- module ClassMethods
74
- def connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
75
- def lease_connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
76
- def with_connection: [T] () { () -> T } -> T
77
-
78
- private
79
- def ar_class: -> singleton(ActiveRecord::Base)
80
- end
81
- end
82
82
  end
@@ -34,15 +34,15 @@ module ActiveRecordCompose
34
34
  type destroy_context_type = ((^() -> boolish) | (^(ar_like) -> boolish))
35
35
  type condition_type = ((^() -> boolish) | (^(ar_like) -> boolish))
36
36
 
37
- class InnerModelCollection
37
+ class ComposedCollection
38
38
  include ::Enumerable[ar_like]
39
39
 
40
- def each: () { (ar_like) -> void } -> InnerModelCollection | () -> Enumerator[ar_like, self]
40
+ def each: () { (ar_like) -> void } -> ComposedCollection | () -> Enumerator[ar_like, self]
41
41
  def <<: (ar_like) -> self
42
42
  def push: (ar_like, ?destroy: (bool | Symbol | destroy_context_type), ?if: (nil | Symbol | condition_type)) -> self
43
43
  def empty?: -> bool
44
44
  def clear: -> self
45
- def delete: (ar_like) -> InnerModelCollection?
45
+ def delete: (ar_like) -> ComposedCollection?
46
46
  end
47
47
 
48
48
  class Model
@@ -69,6 +69,9 @@ 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.persisted_flag_callback_control: () -> boolish
73
+ def self.persisted_flag_callback_control=: (boolish) -> untyped
74
+
72
75
  def self.delegate_attribute: (*untyped methods, to: untyped, ?allow_nil: untyped?, ?private: untyped?) -> untyped
73
76
  def self.connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
74
77
  def self.lease_connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
@@ -84,7 +87,9 @@ module ActiveRecordCompose
84
87
  def id: -> untyped
85
88
 
86
89
  private
87
- def models: -> InnerModelCollection
90
+ def models: -> ComposedCollection
91
+ def with_callbacks: (?context: (nil | :create | :update)) { () -> bool } -> bool
92
+ def callback_context: (?context: (nil | :create | :update)) -> (:create | :update)
88
93
  def validate_models: -> void
89
94
  def save_models: (bang: bool) -> bool
90
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.6.3
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-01-31 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:
@@ -37,12 +37,12 @@ files:
37
37
  - LICENSE.txt
38
38
  - README.md
39
39
  - lib/active_record_compose.rb
40
+ - lib/active_record_compose/composed_collection.rb
40
41
  - lib/active_record_compose/delegate_attribute.rb
41
- - lib/active_record_compose/inner_model.rb
42
- - lib/active_record_compose/inner_model_collection.rb
43
42
  - lib/active_record_compose/model.rb
44
43
  - lib/active_record_compose/transaction_support.rb
45
44
  - lib/active_record_compose/version.rb
45
+ - lib/active_record_compose/wrapped_model.rb
46
46
  - sig/_internal/package_private.rbs
47
47
  - sig/active_record_compose.rbs
48
48
  homepage: https://github.com/hamajyotan/active_record_compose
@@ -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.6.3
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: