activerecord 7.2.0.beta1 → 7.2.0.beta2

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: d8f1dab654da16e8ee509ad6666ae0ed76c264fc0ee14e9c9def0134b729bb3a
4
- data.tar.gz: 13e0b150714cb4389adcfc67ff3f4ff1a93b4df35da4b9711432259401218672
3
+ metadata.gz: 79dcd5171d733c47a82a63fd34a602529290fc29e1e1011906763b5a46bec471
4
+ data.tar.gz: b910e80c8172f01a7aabe42b3b6fb12e11f704c7951972684d1694d136b05520
5
5
  SHA512:
6
- metadata.gz: ff57b5e598733b4b307cd757710fa043fa7669673f317263bfd0e0074bf4df6373ddb14c1ade8584d8cf5a7489a4d6c08d604cdca461439fafea2f0ee8b59823
7
- data.tar.gz: 4801e69d0dc1006cfa3d6081c14380c7e5c00341136df95aafd812093bba843d4e7ed0bdc423d8c43056c9b2b3d4a434431be08dc724d23a762514e102008a2b
6
+ metadata.gz: 5126184906916972f44998d4180a0975a34504341702aa941b065a1eec31014e4066ce5e76a34d7270d4e58e4ab5e068806cdbb2d5bb3177552406b7ce781c84
7
+ data.tar.gz: 876047d057f0103a6e255880ffe12d4625bbbc91e81df3cd1eee22e08d853740c1063a1df7883efe805f56c17abd115e9e5b0c57241d5ab1387eb5fb65214df6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## Rails 7.2.0.beta2 (June 04, 2024) ##
2
+
3
+ * The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
4
+
5
+ *Xavier Noria*
6
+
7
+ * The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
8
+
9
+ *Xavier Noria*
10
+
11
+ * Define `ActiveRecord::Transaction#uuid`, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.
12
+
13
+ *Xavier Noria*
14
+
1
15
  ## Rails 7.2.0.beta1 (May 29, 2024) ##
2
16
 
3
17
  * Fix inference of association model on nested models with the same demodularized name.
@@ -74,7 +74,7 @@ module ActiveRecord
74
74
  # Connections can be obtained and used from a connection pool in several
75
75
  # ways:
76
76
  #
77
- # 1. Simply use {ActiveRecord::Base.lease_connection}[rdoc-ref:ConnectionHandling.connection].
77
+ # 1. Simply use {ActiveRecord::Base.lease_connection}[rdoc-ref:ConnectionHandling#lease_connection].
78
78
  # When you're done with the connection(s) and wish it to be returned to the pool, you call
79
79
  # {ActiveRecord::Base.connection_handler.clear_active_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_active_connections!].
80
80
  # This is the default behavior for Active Record when used in conjunction with
@@ -305,7 +305,7 @@ module ActiveRecord
305
305
  def connection
306
306
  ActiveRecord.deprecator.warn(<<~MSG)
307
307
  ActiveRecord::ConnectionAdapters::ConnectionPool#connection is deprecated
308
- and will be removed in Rails 7.3. Use #lease_connection instead.
308
+ and will be removed in Rails 8.0. Use #lease_connection instead.
309
309
  MSG
310
310
  lease_connection
311
311
  end
@@ -277,6 +277,7 @@ module ActiveRecord
277
277
  type_casted_binds: -> { type_casted_binds(binds) },
278
278
  name: name,
279
279
  connection: self,
280
+ transaction: current_transaction.presence,
280
281
  cached: true
281
282
  }
282
283
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/digest"
4
+
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters
5
7
  # = Active Record Connection Adapters Transaction State
@@ -107,6 +109,7 @@ module ActiveRecord
107
109
  def initialize; end
108
110
  def state; end
109
111
  def closed?; true; end
112
+ alias_method :blank?, :closed?
110
113
  def open?; false; end
111
114
  def joinable?; false; end
112
115
  def add_record(record, _ = true); end
@@ -119,6 +122,7 @@ module ActiveRecord
119
122
  def before_commit; yield; end
120
123
  def after_commit; yield; end
121
124
  def after_rollback; end # noop
125
+ def uuid; Digest::UUID.nil_uuid; end
122
126
  end
123
127
 
124
128
  class Transaction < ActiveRecord::Transaction # :nodoc:
@@ -138,7 +142,7 @@ module ActiveRecord
138
142
  @run_commit_callbacks = run_commit_callbacks
139
143
  @lazy_enrollment_records = nil
140
144
  @dirty = false
141
- @instrumenter = TransactionInstrumenter.new(connection: connection)
145
+ @instrumenter = TransactionInstrumenter.new(connection: connection, transaction: self)
142
146
  end
143
147
 
144
148
  def dirty!
@@ -269,8 +273,6 @@ module ActiveRecord
269
273
 
270
274
  def full_rollback?; true; end
271
275
  def joinable?; @joinable; end
272
- def closed?; false; end
273
- def open?; !closed?; end
274
276
 
275
277
  private
276
278
  def unique_records
@@ -1118,6 +1118,7 @@ module ActiveRecord
1118
1118
  statement_name: statement_name,
1119
1119
  async: async,
1120
1120
  connection: self,
1121
+ transaction: current_transaction.presence,
1121
1122
  row_count: 0,
1122
1123
  &block
1123
1124
  )
@@ -226,7 +226,7 @@ module ActiveRecord
226
226
 
227
227
  ActiveRecord.deprecator.warn(<<~MSG)
228
228
  Defining enums with keyword arguments is deprecated and will be removed
229
- in Rails 7.3. Positional arguments should be used instead:
229
+ in Rails 8.0. Positional arguments should be used instead:
230
230
 
231
231
  #{definitions.map { |name, values| "enum :#{name}, #{values}" }.join("\n")}
232
232
  MSG
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
  MAJOR = 7
11
11
  MINOR = 2
12
12
  TINY = 0
13
- PRE = "beta1"
13
+ PRE = "beta2"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -187,7 +187,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
187
187
  if config.active_record.warn_on_records_fetched_greater_than
188
188
  ActiveRecord.deprecator.warn <<~MSG.squish
189
189
  `config.active_record.warn_on_records_fetched_greater_than` is deprecated and will be
190
- removed in Rails 7.3.
190
+ removed in Rails 8.0.
191
191
  Please subscribe to `sql.active_record` notifications and access the row count field to
192
192
  detect large result set sizes.
193
193
  MSG
@@ -746,7 +746,7 @@ module ActiveRecord
746
746
  VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock,
747
747
  :limit, :offset, :joins, :left_outer_joins, :annotate,
748
748
  :includes, :eager_load, :preload, :from, :readonly,
749
- :having, :optimizer_hints])
749
+ :having, :optimizer_hints, :with])
750
750
 
751
751
  # Removes an unwanted relation that is already defined on a chain of relations.
752
752
  # This is useful when passing around chains of relations and would like to
@@ -446,7 +446,7 @@ module ActiveRecord
446
446
  db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
447
447
  else
448
448
  ActiveRecord.deprecator.warn(<<~MSG.squish)
449
- Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 7.3. Pass a
449
+ Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 8.0. Pass a
450
450
  `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object instead.
451
451
  MSG
452
452
 
@@ -531,7 +531,7 @@ module ActiveRecord
531
531
  def schema_cache_env
532
532
  if ENV["SCHEMA_CACHE"]
533
533
  ActiveRecord.deprecator.warn(<<~MSG.squish)
534
- Setting `ENV["SCHEMA_CACHE"]` is deprecated and will be removed in Rails 7.3.
534
+ Setting `ENV["SCHEMA_CACHE"]` is deprecated and will be removed in Rails 8.0.
535
535
  Configure the `:schema_cache_path` in the database configuration instead.
536
536
  MSG
537
537
 
@@ -1,6 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/digest"
4
+
3
5
  module ActiveRecord
6
+ # This abstract class specifies the interface to interact with the current transaction state.
7
+ #
8
+ # Any other methods not specified here are considered to be private interfaces.
9
+ #
10
+ # == Callbacks
11
+ #
12
+ # After updating the database state, you may sometimes need to perform some extra work, or reflect these
13
+ # changes in a remote system like clearing or updating a cache:
14
+ #
15
+ # def publish_article(article)
16
+ # article.update!(published: true)
17
+ # NotificationService.article_published(article)
18
+ # end
19
+ #
20
+ # The above code works but has one important flaw, which is that it no longer works properly if called inside
21
+ # a transaction, as it will interact with the remote system before the changes are persisted:
22
+ #
23
+ # Article.transaction do
24
+ # article = create_article(article)
25
+ # publish_article(article)
26
+ # end
27
+ #
28
+ # The callbacks offered by ActiveRecord::Transaction allow to rewriting this method in a way that is compatible
29
+ # with transactions:
30
+ #
31
+ # def publish_article(article)
32
+ # article.update!(published: true)
33
+ # Article.current_transaction.after_commit do
34
+ # NotificationService.article_published(article)
35
+ # end
36
+ # end
37
+ #
38
+ # In the above example, if +publish_article+ is called inside a transaction, the callback will be invoked
39
+ # after the transaction is successfully committed, and if called outside a transaction, the callback will be invoked
40
+ # immediately.
41
+ #
42
+ # == Caveats
43
+ #
44
+ # When using after_commit callbacks, it is important to note that if the callback raises an error, the transaction
45
+ # won't be rolled back. Relying solely on these to synchronize state between multiple systems may lead to consistency issues.
4
46
  class Transaction
5
47
  class Callback # :nodoc:
6
48
  def initialize(event, callback)
@@ -23,6 +65,7 @@ module ActiveRecord
23
65
 
24
66
  def initialize # :nodoc:
25
67
  @callbacks = nil
68
+ @uuid = nil
26
69
  end
27
70
 
28
71
  # Registers a block to be called before the current transaction is fully committed.
@@ -32,6 +75,8 @@ module ActiveRecord
32
75
  # If the current transaction has a parent transaction, the callback is transferred to
33
76
  # the parent when the current transaction commits, or dropped when the current transaction
34
77
  # is rolled back. This operation is repeated until the outermost transaction is reached.
78
+ #
79
+ # If the callback raises an error, the transaction is rolled back.
35
80
  def before_commit(&block)
36
81
  (@callbacks ||= []) << Callback.new(:before_commit, block)
37
82
  end
@@ -43,6 +88,8 @@ module ActiveRecord
43
88
  # If the current transaction has a parent transaction, the callback is transferred to
44
89
  # the parent when the current transaction commits, or dropped when the current transaction
45
90
  # is rolled back. This operation is repeated until the outermost transaction is reached.
91
+ #
92
+ # If the callback raises an error, the transaction remains committed.
46
93
  def after_commit(&block)
47
94
  (@callbacks ||= []) << Callback.new(:after_commit, block)
48
95
  end
@@ -60,8 +107,24 @@ module ActiveRecord
60
107
  (@callbacks ||= []) << Callback.new(:after_rollback, block)
61
108
  end
62
109
 
110
+ # Returns true if a transaction was started.
111
+ def open?
112
+ true
113
+ end
114
+
115
+ # Returns true if no transaction is currently active.
116
+ def closed?
117
+ false
118
+ end
119
+ alias_method :blank?, :closed?
120
+
121
+ # Returns a UUID for this transaction.
122
+ def uuid
123
+ @uuid ||= Digest::UUID.uuid_v4
124
+ end
125
+
63
126
  protected
64
- def append_callbacks(callbacks)
127
+ def append_callbacks(callbacks) # :nodoc:
65
128
  (@callbacks ||= []).concat(callbacks)
66
129
  end
67
130
  end
@@ -188,6 +188,27 @@ module ActiveRecord
188
188
  # #after_commit is a good spot to put in a hook to clearing a cache since clearing it from
189
189
  # within a transaction could trigger the cache to be regenerated before the database is updated.
190
190
  #
191
+ # ==== NOTE: Callbacks are deduplicated per callback by filter.
192
+ #
193
+ # Trying to define multiple callbacks with the same filter will result in a single callback being run.
194
+ #
195
+ # For example:
196
+ #
197
+ # after_commit :do_something
198
+ # after_commit :do_something # only the last one will be called
199
+ #
200
+ # This applies to all variations of <tt>after_*_commit</tt> callbacks as well.
201
+ #
202
+ # after_commit :do_something
203
+ # after_create_commit :do_something
204
+ # after_save_commit :do_something
205
+ #
206
+ # It is recommended to use the +on:+ option to specify when the callback should be run.
207
+ #
208
+ # after_commit :do_something, on: [:create, :update]
209
+ #
210
+ # This is equivalent to using +after_create_commit+ and +after_update_commit+, but will not be deduplicated.
211
+ #
191
212
  # === Caveats
192
213
  #
193
214
  # If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
@@ -214,7 +235,13 @@ module ActiveRecord
214
235
  end
215
236
  end
216
237
 
217
- # Returns the current transaction. See ActiveRecord::Transactions API docs.
238
+ # Returns a representation of the current transaction state,
239
+ # which can be a top level transaction, a savepoint, or the absence of a transaction.
240
+ #
241
+ # An object is always returned, whether or not a transaction is currently active.
242
+ # To check if a transaction was opened, use <tt>current_transaction.open?</tt>.
243
+ #
244
+ # See the ActiveRecord::Transaction documentation for detailed behavior.
218
245
  def current_transaction
219
246
  connection_pool.active_connection&.current_transaction || ConnectionAdapters::TransactionManager::NULL_TRANSACTION
220
247
  end
data/lib/active_record.rb CHANGED
@@ -347,14 +347,14 @@ module ActiveRecord
347
347
  def self.commit_transaction_on_non_local_return
348
348
  ActiveRecord.deprecator.warn <<-WARNING.squish
349
349
  `Rails.application.config.active_record.commit_transaction_on_non_local_return`
350
- is deprecated and will be removed in Rails 7.3.
350
+ is deprecated and will be removed in Rails 8.0.
351
351
  WARNING
352
352
  end
353
353
 
354
354
  def self.commit_transaction_on_non_local_return=(value)
355
355
  ActiveRecord.deprecator.warn <<-WARNING.squish
356
356
  `Rails.application.config.active_record.commit_transaction_on_non_local_return`
357
- is deprecated and will be removed in Rails 7.3.
357
+ is deprecated and will be removed in Rails 8.0.
358
358
  WARNING
359
359
  end
360
360
 
@@ -447,14 +447,14 @@ module ActiveRecord
447
447
  def self.allow_deprecated_singular_associations_name
448
448
  ActiveRecord.deprecator.warn <<-WARNING.squish
449
449
  `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
450
- is deprecated and will be removed in Rails 7.3.
450
+ is deprecated and will be removed in Rails 8.0.
451
451
  WARNING
452
452
  end
453
453
 
454
454
  def self.allow_deprecated_singular_associations_name=(value)
455
455
  ActiveRecord.deprecator.warn <<-WARNING.squish
456
456
  `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
457
- is deprecated and will be removed in Rails 7.3.
457
+ is deprecated and will be removed in Rails 8.0.
458
458
  WARNING
459
459
  end
460
460
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0.beta1
4
+ version: 7.2.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-29 00:00:00.000000000 Z
11
+ date: 2024-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.2.0.beta1
19
+ version: 7.2.0.beta2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.2.0.beta1
26
+ version: 7.2.0.beta2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 7.2.0.beta1
33
+ version: 7.2.0.beta2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 7.2.0.beta1
40
+ version: 7.2.0.beta2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: timeout
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -475,10 +475,10 @@ licenses:
475
475
  - MIT
476
476
  metadata:
477
477
  bug_tracker_uri: https://github.com/rails/rails/issues
478
- changelog_uri: https://github.com/rails/rails/blob/v7.2.0.beta1/activerecord/CHANGELOG.md
479
- documentation_uri: https://api.rubyonrails.org/v7.2.0.beta1/
478
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.0.beta2/activerecord/CHANGELOG.md
479
+ documentation_uri: https://api.rubyonrails.org/v7.2.0.beta2/
480
480
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
481
- source_code_uri: https://github.com/rails/rails/tree/v7.2.0.beta1/activerecord
481
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.0.beta2/activerecord
482
482
  rubygems_mfa_required: 'true'
483
483
  post_install_message:
484
484
  rdoc_options:
@@ -493,11 +493,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
493
493
  version: 3.1.0
494
494
  required_rubygems_version: !ruby/object:Gem::Requirement
495
495
  requirements:
496
- - - ">="
496
+ - - ">"
497
497
  - !ruby/object:Gem::Version
498
- version: '0'
498
+ version: 1.3.1
499
499
  requirements: []
500
- rubygems_version: 3.5.10
500
+ rubygems_version: 3.3.27
501
501
  signing_key:
502
502
  specification_version: 4
503
503
  summary: Object-relational mapper framework (part of Rails).