activerecord 7.2.0.beta1 → 7.2.0.beta2

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: 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).