active_record_compose 0.2.1 → 0.3.1

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: 0c3cb23854b3caafb1f25c297b1d12fb7693c5af5d8e7f917ce3117e5334afa0
4
- data.tar.gz: fe905d6071cc4c491fadd68c35b36540b57881d78b6c398acaf2e573d766912c
3
+ metadata.gz: 2c83677cc55d1c45bfa440db7ca21b2924ffec080a025503b892ec3f0245a6b8
4
+ data.tar.gz: d5a01db0286b3bb0527b4e16692b62fa468035fc091449e7607f2f709b75b866
5
5
  SHA512:
6
- metadata.gz: 6a8850ebb01e4705f658bbc65c2cc10366214a2c34787b3d6c6228c34ac405aa00b548212747ef5429fe26eabe1633bf5af9d1019bd95094c1cfd79897811d4c
7
- data.tar.gz: a531f7980d9d5ed490aa8c35927176511db6ff81f81009d02ac4121a04abe57efd6ac4dc5db8f353b4ef03c18214c73f246a1c6c8e43e235d1065d436538de31
6
+ metadata.gz: 44a5cca81d044619077855a534063bd2a28a42ece83f34b2605c6c03192f89066e14b8e3c02309e6c52d25608fe2dad0b519cfd9a32ed3d8f1f8fc76ec1105e2
7
+ data.tar.gz: 2245da3f3053b93ba7c6c2357eecb08a3c069d99e90645fd0a4c7a2b55b5704fc59dbd22e7a70a1f49d397a59cf9c864c39681eb0d7f65d885f797fe973e95a4
data/.rubocop.yml CHANGED
@@ -33,6 +33,9 @@ Layout/LineLength:
33
33
  Metrics/BlockLength:
34
34
  Enabled: false
35
35
 
36
+ Metrics/MethodLength:
37
+ Enabled: false
38
+
36
39
  Naming/BlockForwarding:
37
40
  Enabled: false
38
41
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.1] - 2024-03-17
4
+
5
+ - purge nodoc definitions from type signature
6
+ - support `ActiveRecord::Base#lease_connection`
7
+
8
+ ## [0.3.0] - 2024-02-24
9
+
10
+ - strictify type checking
11
+ - testing with CI even in the head version of rails
12
+ - consolidate the main process of saving into the `#save` method
13
+ - leave transaction control to ActiveRecord::Transactions
14
+ - execution of `before_commit`, `after_commit` and `after_rollback` hook is delayed until after the database commit (or rollback).
15
+
3
16
  ## [0.2.1] - 2024-01-31
4
17
 
5
18
  - in `#save` (without bang), `ActiveRecord::RecordInvalid` error is not passed outward.
@@ -38,23 +38,26 @@ module ActiveRecordCompose
38
38
  extend ActiveSupport::Concern
39
39
 
40
40
  included do
41
- class_attribute :delegated_attributes, instance_writer: false
41
+ __skip__ = class_attribute :delegated_attributes, instance_writer: false
42
42
  end
43
43
 
44
- class_methods do
44
+ module ClassMethods
45
45
  # Defines the reader and writer for the specified attribute.
46
46
  #
47
47
  def delegate_attribute(*attributes, to:, **options)
48
- delegates = attributes.flat_map do |attribute|
49
- reader = attribute
50
- writer = "#{attribute}="
48
+ __skip__ =
49
+ begin
50
+ delegates = attributes.flat_map do |attribute|
51
+ reader = attribute
52
+ writer = "#{attribute}="
51
53
 
52
- [reader, writer]
53
- end
54
+ [reader, writer]
55
+ end
54
56
 
55
- delegate(*delegates, to:, **options)
56
- delegated_attributes = (self.delegated_attributes ||= [])
57
- attributes.each { delegated_attributes.push(_1.to_s) }
57
+ delegate(*delegates, to:, **options)
58
+ delegated_attributes = (self.delegated_attributes ||= [])
59
+ attributes.each { delegated_attributes.push(_1.to_s) }
60
+ end
58
61
  end
59
62
  end
60
63
 
@@ -63,11 +66,11 @@ module ActiveRecordCompose
63
66
  #
64
67
  # @return [Hash] hash with the attribute name as key and the attribute value as value.
65
68
  def attributes
66
- # steep:ignore all
67
- attrs = defined?(super) ? super : {}
68
- # steep:ignore end
69
- # @type var attrs: Hash[String, untyped]
70
- attrs.merge(delegated_attributes.to_h { [_1, public_send(_1)] })
69
+ attrs = __skip__ = defined?(super) ? super : {}
70
+ delegates = __skip__ = delegated_attributes
71
+
72
+ # @type var delegates: Array[untyped]
73
+ attrs.merge(delegates.to_h { [_1, public_send(_1)] })
71
74
  end
72
75
  end
73
76
  end
@@ -65,7 +65,7 @@ module ActiveRecordCompose
65
65
  # @return [Boolean]
66
66
  def ==(other)
67
67
  return false unless self.class == other.class
68
- return false unless __raw_model == other.__raw_model
68
+ return false unless (__skip__ = (__raw_model == other.__raw_model))
69
69
  return false unless context == other.context
70
70
 
71
71
  true
@@ -14,7 +14,7 @@ module ActiveRecordCompose
14
14
  def each
15
15
  return enum_for(:each) unless block_given?
16
16
 
17
- models.each { yield _1.__raw_model }
17
+ __skip__ = models.each { yield _1.__raw_model }
18
18
  self
19
19
  end
20
20
 
@@ -73,7 +73,7 @@ module ActiveRecordCompose
73
73
  def __each_by_wrapped
74
74
  return enum_for(:__each_by_wrapped) unless block_given?
75
75
 
76
- models.each { yield _1 if _1.__raw_model }
76
+ __skip__ = models.each { yield _1 if _1.__raw_model }
77
77
  self
78
78
  end
79
79
 
@@ -2,15 +2,16 @@
2
2
 
3
3
  require 'active_record_compose/delegate_attribute'
4
4
  require 'active_record_compose/inner_model_collection'
5
+ require 'active_record_compose/transaction_support'
5
6
 
6
7
  module ActiveRecordCompose
7
8
  class Model
8
9
  include ActiveModel::Model
9
10
  include ActiveModel::Validations::Callbacks
10
11
  include ActiveModel::Attributes
11
- include ActiveRecord::Transactions
12
12
 
13
13
  include ActiveRecordCompose::DelegateAttribute
14
+ include ActiveRecordCompose::TransactionSupport
14
15
 
15
16
  define_model_callbacks :save
16
17
  define_model_callbacks :create
@@ -19,9 +20,7 @@ module ActiveRecordCompose
19
20
  validate :validate_models
20
21
 
21
22
  def initialize(attributes = {})
22
- # steep:ignore all
23
- super(attributes)
24
- # steep:ignore end
23
+ __skip__ = super(attributes)
25
24
  end
26
25
 
27
26
  # Save the models that exist in models.
@@ -33,9 +32,11 @@ module ActiveRecordCompose
33
32
  def save
34
33
  return false if invalid?
35
34
 
36
- save_in_transaction { save_models(bang: false) }
37
- rescue ActiveRecord::RecordInvalid
38
- false
35
+ with_transaction_returning_status do
36
+ run_callbacks(:save) { save_models(bang: false) }
37
+ rescue ActiveRecord::RecordInvalid
38
+ false
39
+ end
39
40
  end
40
41
 
41
42
  # Save the models that exist in models.
@@ -46,7 +47,9 @@ module ActiveRecordCompose
46
47
  def save!
47
48
  valid? || raise_validation_error
48
49
 
49
- save_in_transaction { save_models(bang: true) } || raise_on_save_error
50
+ with_transaction_returning_status do
51
+ run_callbacks(:save) { save_models(bang: true) }
52
+ end || raise_on_save_error
50
53
  end
51
54
 
52
55
  # Behavior is same to `#save`, but `before_create` and `after_create` hooks fires.
@@ -78,9 +81,11 @@ module ActiveRecordCompose
78
81
  assign_attributes(attributes)
79
82
  return false if invalid?
80
83
 
81
- save_in_transaction { run_callbacks(:create) { save_models(bang: false) } }
82
- rescue ActiveRecord::RecordInvalid
83
- false
84
+ with_transaction_returning_status do
85
+ run_callbacks(:save) { run_callbacks(:create) { save_models(bang: false) } }
86
+ rescue ActiveRecord::RecordInvalid
87
+ false
88
+ end
84
89
  end
85
90
 
86
91
  # Behavior is same to `#create`, but raises an exception prematurely on failure.
@@ -89,7 +94,9 @@ module ActiveRecordCompose
89
94
  assign_attributes(attributes)
90
95
  valid? || raise_validation_error
91
96
 
92
- save_in_transaction { run_callbacks(:create) { save_models(bang: true) } } || raise_on_save_error
97
+ with_transaction_returning_status do
98
+ run_callbacks(:save) { run_callbacks(:create) { save_models(bang: true) } }
99
+ end || raise_on_save_error
93
100
  end
94
101
 
95
102
  # Behavior is same to `#save`, but `before_update` and `after_update` hooks fires.
@@ -121,9 +128,11 @@ module ActiveRecordCompose
121
128
  assign_attributes(attributes)
122
129
  return false if invalid?
123
130
 
124
- save_in_transaction { run_callbacks(:update) { save_models(bang: false) } }
125
- rescue ActiveRecord::RecordInvalid
126
- false
131
+ with_transaction_returning_status do
132
+ run_callbacks(:save) { run_callbacks(:update) { save_models(bang: false) } }
133
+ rescue ActiveRecord::RecordInvalid
134
+ false
135
+ end
127
136
  end
128
137
 
129
138
  # Behavior is same to `#update`, but raises an exception prematurely on failure.
@@ -132,31 +141,19 @@ module ActiveRecordCompose
132
141
  assign_attributes(attributes)
133
142
  valid? || raise_validation_error
134
143
 
135
- save_in_transaction { run_callbacks(:update) { save_models(bang: true) } } || raise_on_save_error
144
+ with_transaction_returning_status do
145
+ run_callbacks(:save) { run_callbacks(:update) { save_models(bang: true) } }
146
+ end || raise_on_save_error
136
147
  end
137
148
 
138
149
  private
139
150
 
140
151
  def models = @__models ||= ActiveRecordCompose::InnerModelCollection.new
141
152
 
142
- def wrapped_models = models.__each_by_wrapped
153
+ def wrapped_models = (__skip__ = models.__each_by_wrapped)
143
154
 
144
155
  def validate_models = wrapped_models.select { _1.invalid? }.each { errors.merge!(_1) }
145
156
 
146
- def save_in_transaction(&block)
147
- run_callbacks(:commit) do
148
- result = ::ActiveRecord::Base.transaction do
149
- raise ActiveRecord::Rollback unless run_callbacks(:save, &block)
150
-
151
- true
152
- end
153
- result.present?
154
- rescue StandardError
155
- run_callbacks :rollback
156
- raise
157
- end.present?
158
- end
159
-
160
157
  def save_models(bang:) = wrapped_models.all? { bang ? _1.save! : _1.save }
161
158
 
162
159
  def raise_validation_error = raise ActiveRecord::RecordInvalid, self
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecordCompose
4
+ module TransactionSupport
5
+ extend ActiveSupport::Concern
6
+ include ActiveRecord::Transactions
7
+
8
+ module ClassMethods
9
+ def lease_connection
10
+ if ActiveRecord::Base.respond_to?(:lease_connection)
11
+ __skip__ = ActiveRecord::Base.lease_connection
12
+ else
13
+ ActiveRecord::Base.connection
14
+ end
15
+ end
16
+
17
+ def connection = ActiveRecord::Base.connection
18
+
19
+ def composite_primary_key? = false
20
+ end
21
+
22
+ def id = nil
23
+
24
+ def trigger_transactional_callbacks? = true
25
+ def restore_transaction_record_state(_force_restore_state = false) = nil # rubocop:disable Style/OptionalBooleanParameter
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.1'
5
5
  end
@@ -24,13 +24,11 @@ module ActiveRecordCompose
24
24
  module DelegateAttribute
25
25
  extend ActiveSupport::Concern
26
26
 
27
- def delegated_attribute: -> Array[untyped]
28
27
  def attributes: -> Hash[String, untyped]
29
- def delegated_attributes: -> Array[untyped]
30
- def delegated_attributes=: (Array[untyped]) -> void
31
28
 
32
- def self.class_attribute: (untyped, ?untyped) -> untyped
33
- def delegate: (*untyped) -> untyped
29
+ module ClassMethods
30
+ def delegate_attribute: (*untyped methods, to: untyped?, **untyped) -> untyped
31
+ end
34
32
  end
35
33
 
36
34
  class InnerModelCollection
@@ -43,7 +41,6 @@ module ActiveRecordCompose
43
41
  def empty?: -> bool
44
42
  def clear: -> self
45
43
  def delete: (_ARLike | InnerModel, ?context: context_types) -> InnerModelCollection?
46
- def __each_by_wrapped: () { (InnerModel) -> void } -> InnerModelCollection | () -> Enumerator[InnerModel, self]
47
44
 
48
45
  private
49
46
  def models: -> Array[InnerModel]
@@ -60,7 +57,6 @@ module ActiveRecordCompose
60
57
  def invalid?: -> bool
61
58
  def valid?: -> bool
62
59
  def ==: (untyped) -> bool
63
- def __raw_model: -> _ARLike
64
60
 
65
61
  private
66
62
  attr_reader model: _ARLike
@@ -70,9 +66,12 @@ module ActiveRecordCompose
70
66
  extend ActiveModel::Callbacks
71
67
  include ActiveModel::Model
72
68
  include ActiveModel::Validations::Callbacks
69
+ extend ActiveModel::Validations::ClassMethods
73
70
  include ActiveModel::Attributes
74
- include ActiveRecord::Transactions
75
71
  include DelegateAttribute
72
+ extend DelegateAttribute::ClassMethods
73
+ include TransactionSupport
74
+ extend TransactionSupport::ClassMethods
76
75
 
77
76
  @__models: InnerModelCollection
78
77
 
@@ -88,13 +87,20 @@ module ActiveRecordCompose
88
87
  def models: -> InnerModelCollection
89
88
  def wrapped_models: -> Enumerator[InnerModel, InnerModelCollection]
90
89
  def validate_models: -> void
91
- def save_in_transaction: { -> bool } -> untyped
92
90
  def save_models: (bang: bool) -> bool
93
91
  def raise_validation_error: -> bot
94
92
  def raise_on_save_error: -> bot
95
93
  def raise_on_save_error_message: -> String
94
+ end
95
+
96
+ module TransactionSupport
97
+ include ActiveRecord::Transactions
98
+
99
+ def id: -> untyped
96
100
 
97
- def self.validate: (*untyped) -> untyped
98
- def run_callbacks: (untyped kind) ?{ () -> untyped } -> untyped
101
+ module ClassMethods
102
+ def connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
103
+ def lease_connection: -> ActiveRecord::ConnectionAdapters::AbstractAdapter
104
+ end
99
105
  end
100
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamajyotan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-31 00:00:00.000000000 Z
11
+ date: 2024-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -42,6 +42,7 @@ files:
42
42
  - lib/active_record_compose/inner_model.rb
43
43
  - lib/active_record_compose/inner_model_collection.rb
44
44
  - lib/active_record_compose/model.rb
45
+ - lib/active_record_compose/transaction_support.rb
45
46
  - lib/active_record_compose/version.rb
46
47
  - sig/active_record_compose.rbs
47
48
  homepage: https://github.com/hamajyotan/active_record_compose
@@ -51,7 +52,7 @@ metadata:
51
52
  homepage_uri: https://github.com/hamajyotan/active_record_compose
52
53
  source_code_uri: https://github.com/hamajyotan/active_record_compose
53
54
  changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
54
- documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.2.1
55
+ documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.3.1
55
56
  rubygems_mfa_required: 'true'
56
57
  post_install_message:
57
58
  rdoc_options: []
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  - !ruby/object:Gem::Version
69
70
  version: '0'
70
71
  requirements: []
71
- rubygems_version: 3.5.5
72
+ rubygems_version: 3.5.6
72
73
  signing_key:
73
74
  specification_version: 4
74
75
  summary: activemodel form object pattern