activerecord 7.1.1 → 7.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +177 -0
- data/README.rdoc +1 -0
- data/lib/active_record/associations/association.rb +2 -1
- data/lib/active_record/associations/preloader/association.rb +4 -1
- data/lib/active_record/associations.rb +15 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +13 -9
- data/lib/active_record/attribute_methods.rb +1 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +11 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -2
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +13 -4
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +3 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -5
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +32 -33
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -3
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +1 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +9 -1
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +41 -7
- data/lib/active_record/delegated_type.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +7 -1
- data/lib/active_record/encryption/encrypted_attribute_type.rb +4 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +0 -15
- data/lib/active_record/enum.rb +6 -9
- data/lib/active_record/errors.rb +5 -4
- data/lib/active_record/fixtures.rb +16 -0
- data/lib/active_record/future_result.rb +1 -0
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/insert_all.rb +3 -3
- data/lib/active_record/internal_metadata.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +8 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +9 -5
- data/lib/active_record/model_schema.rb +5 -5
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/normalization.rb +8 -0
- data/lib/active_record/persistence.rb +4 -3
- data/lib/active_record/promise.rb +1 -1
- data/lib/active_record/railties/controller_runtime.rb +2 -1
- data/lib/active_record/railties/databases.rake +5 -5
- data/lib/active_record/reflection.rb +13 -1
- data/lib/active_record/relation/calculations.rb +28 -1
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation.rb +18 -3
- data/lib/active_record/runtime_registry.rb +15 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/secure_token.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +5 -5
- data/lib/arel/nodes/homogeneous_in.rb +1 -1
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f7c51f040979b7650eb209b0dc856a0877bccc968dd99cde06e3cf1776dd638
|
4
|
+
data.tar.gz: b81eca56b185f087c95b6691b307ff1c9c63d0d03ff650b729e943888f053152
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f68dc9e6cdccf23f5467810a68083564760601aa3c82b4c85720cfb2c39500439a86bb63c2ce8fea37337de6fc4f157722300c691cfd239e92732569b5c20f6
|
7
|
+
data.tar.gz: 6f8382df74c2c16b873cab0effeda0a3ef3e578d5087e435d7d2f8c6890dcf0d85e2211f2bc890182af49e836b09e4e345e2b9bc37eb8472814e98bb6636b005
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,176 @@
|
|
1
|
+
## Rails 7.1.3 (January 16, 2024) ##
|
2
|
+
|
3
|
+
* Fix Migrations with versions older than 7.1 validating options given to
|
4
|
+
`add_reference`.
|
5
|
+
|
6
|
+
*Hartley McGuire*
|
7
|
+
|
8
|
+
* Ensure `reload` sets correct owner for each association.
|
9
|
+
|
10
|
+
*Dmytro Savochkin*
|
11
|
+
|
12
|
+
* Fix view runtime for controllers with async queries.
|
13
|
+
|
14
|
+
*fatkodima*
|
15
|
+
|
16
|
+
* Fix `load_async` to work with query cache.
|
17
|
+
|
18
|
+
*fatkodima*
|
19
|
+
|
20
|
+
* Fix polymorphic `belongs_to` to correctly use parent's `query_constraints`.
|
21
|
+
|
22
|
+
*fatkodima*
|
23
|
+
|
24
|
+
* Fix `Preloader` to not generate a query for already loaded association with `query_constraints`.
|
25
|
+
|
26
|
+
*fatkodima*
|
27
|
+
|
28
|
+
* Fix multi-database polymorphic preloading with equivalent table names.
|
29
|
+
|
30
|
+
When preloading polymorphic associations, if two models pointed to two
|
31
|
+
tables with the same name but located in different databases, the
|
32
|
+
preloader would only load one.
|
33
|
+
|
34
|
+
*Ari Summer*
|
35
|
+
|
36
|
+
* Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
|
37
|
+
|
38
|
+
*Maxime Réty*
|
39
|
+
|
40
|
+
* Fix `find_by` to work correctly in presence of composite primary keys.
|
41
|
+
|
42
|
+
*fatkodima*
|
43
|
+
|
44
|
+
* Fix async queries sometimes returning a raw result if they hit the query cache.
|
45
|
+
|
46
|
+
`ShipPart.async_count` could return a raw integer rather than a Promise
|
47
|
+
if it found the result in the query cache.
|
48
|
+
|
49
|
+
*fatkodima*
|
50
|
+
|
51
|
+
* Fix `Relation#transaction` to not apply a default scope.
|
52
|
+
|
53
|
+
The method was incorrectly setting a default scope around its block:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
Post.where(published: true).transaction do
|
57
|
+
Post.count # SELECT COUNT(*) FROM posts WHERE published = FALSE;
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
*Jean Boussier*
|
62
|
+
|
63
|
+
* Fix calling `async_pluck` on a `none` relation.
|
64
|
+
|
65
|
+
`Model.none.async_pluck(:id)` was returning a naked value
|
66
|
+
instead of a promise.
|
67
|
+
|
68
|
+
*Jean Boussier*
|
69
|
+
|
70
|
+
* Fix calling `load_async` on a `none` relation.
|
71
|
+
|
72
|
+
`Model.none.load_async` was returning a broken result.
|
73
|
+
|
74
|
+
*Lucas Mazza*
|
75
|
+
|
76
|
+
* TrilogyAdapter: ignore `host` if `socket` parameter is set.
|
77
|
+
|
78
|
+
This allows to configure a connection on a UNIX socket via DATABASE_URL:
|
79
|
+
|
80
|
+
```
|
81
|
+
DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
|
82
|
+
```
|
83
|
+
|
84
|
+
*Jean Boussier*
|
85
|
+
|
86
|
+
* Fix `has_secure_token` calls the setter method on initialize.
|
87
|
+
|
88
|
+
*Abeid Ahmed*
|
89
|
+
|
90
|
+
* Allow using `object_id` as a database column name.
|
91
|
+
It was available before rails 7.1 and may be used as a part of polymorphic relationship to `object` where `object` can be any other database record.
|
92
|
+
|
93
|
+
*Mikhail Doronin*
|
94
|
+
|
95
|
+
* Fix `rails db:create:all` to not touch databases before they are created.
|
96
|
+
|
97
|
+
*fatkodima*
|
98
|
+
|
99
|
+
|
100
|
+
## Rails 7.1.2 (November 10, 2023) ##
|
101
|
+
|
102
|
+
* Fix renaming primary key index when renaming a table with a UUID primary key
|
103
|
+
in PostgreSQL.
|
104
|
+
|
105
|
+
*fatkodima*
|
106
|
+
|
107
|
+
* Fix `where(field: values)` queries when `field` is a serialized attribute
|
108
|
+
(for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
|
109
|
+
column).
|
110
|
+
|
111
|
+
*João Alves*
|
112
|
+
|
113
|
+
* Prevent marking broken connections as verified.
|
114
|
+
|
115
|
+
*Daniel Colson*
|
116
|
+
|
117
|
+
* Don't mark Float::INFINITY as changed when reassigning it
|
118
|
+
|
119
|
+
When saving a record with a float infinite value, it shouldn't mark as changed
|
120
|
+
|
121
|
+
*Maicol Bentancor*
|
122
|
+
|
123
|
+
* `ActiveRecord::Base.table_name` now returns `nil` instead of raising
|
124
|
+
"undefined method `abstract_class?` for Object:Class".
|
125
|
+
|
126
|
+
*a5-stable*
|
127
|
+
|
128
|
+
* Fix upserting for custom `:on_duplicate` and `:unique_by` consisting of all
|
129
|
+
inserts keys.
|
130
|
+
|
131
|
+
*fatkodima*
|
132
|
+
|
133
|
+
* Fixed an [issue](https://github.com/rails/rails/issues/49809) where saving a
|
134
|
+
record could innappropriately `dup` its attributes.
|
135
|
+
|
136
|
+
*Jonathan Hefner*
|
137
|
+
|
138
|
+
* Dump schema only for a specific db for rollback/up/down tasks for multiple dbs.
|
139
|
+
|
140
|
+
*fatkodima*
|
141
|
+
|
142
|
+
* Fix `NoMethodError` when casting a PostgreSQL `money` value that uses a
|
143
|
+
comma as its radix point and has no leading currency symbol. For example,
|
144
|
+
when casting `"3,50"`.
|
145
|
+
|
146
|
+
*Andreas Reischuck* and *Jonathan Hefner*
|
147
|
+
|
148
|
+
* Re-enable support for using `enum` with non-column-backed attributes.
|
149
|
+
Non-column-backed attributes must be previously declared with an explicit
|
150
|
+
type. For example:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
class Post < ActiveRecord::Base
|
154
|
+
attribute :topic, :string
|
155
|
+
enum topic: %i[science tech engineering math]
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
*Jonathan Hefner*
|
160
|
+
|
161
|
+
* Raise on `foreign_key:` being passed as an array in associations
|
162
|
+
|
163
|
+
*Nikita Vasilevsky*
|
164
|
+
|
165
|
+
* Return back maximum allowed PostgreSQL table name to 63 characters.
|
166
|
+
|
167
|
+
*fatkodima*
|
168
|
+
|
169
|
+
* Fix detecting `IDENTITY` columns for PostgreSQL < 10.
|
170
|
+
|
171
|
+
*fatkodima*
|
172
|
+
|
173
|
+
|
1
174
|
## Rails 7.1.1 (October 11, 2023) ##
|
2
175
|
|
3
176
|
* Fix auto populating IDENTITY columns for PostgreSQL.
|
@@ -165,6 +338,10 @@
|
|
165
338
|
|
166
339
|
*Adam Hess*
|
167
340
|
|
341
|
+
* Deprecate aliasing non-attributes with `alias_attribute`.
|
342
|
+
|
343
|
+
*Ian Candy*
|
344
|
+
|
168
345
|
* Fix unscope is not working in specific case
|
169
346
|
|
170
347
|
Before:
|
data/README.rdoc
CHANGED
@@ -166,6 +166,7 @@ Active Record is an implementation of the object-relational mapping (ORM)
|
|
166
166
|
pattern[https://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
|
167
167
|
name described by Martin Fowler:
|
168
168
|
|
169
|
+
>>>
|
169
170
|
"An object that wraps a row in a database table or view,
|
170
171
|
encapsulates the database access, and adds domain logic on that data."
|
171
172
|
|
@@ -33,7 +33,8 @@ module ActiveRecord
|
|
33
33
|
# <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
|
34
34
|
# the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
|
35
35
|
class Association # :nodoc:
|
36
|
-
|
36
|
+
attr_accessor :owner
|
37
|
+
attr_reader :target, :reflection, :disable_joins
|
37
38
|
|
38
39
|
delegate :options, to: :reflection
|
39
40
|
|
@@ -17,11 +17,12 @@ module ActiveRecord
|
|
17
17
|
def eql?(other)
|
18
18
|
association_key_name == other.association_key_name &&
|
19
19
|
scope.table_name == other.scope.table_name &&
|
20
|
+
scope.connection_specification_name == other.scope.connection_specification_name &&
|
20
21
|
scope.values_for_queries == other.scope.values_for_queries
|
21
22
|
end
|
22
23
|
|
23
24
|
def hash
|
24
|
-
[association_key_name, scope.table_name, scope.values_for_queries].hash
|
25
|
+
[association_key_name, scope.table_name, scope.connection_specification_name, scope.values_for_queries].hash
|
25
26
|
end
|
26
27
|
|
27
28
|
def records_for(loaders)
|
@@ -38,6 +39,8 @@ module ActiveRecord
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def load_records_for_keys(keys, &block)
|
42
|
+
return [] if keys.empty?
|
43
|
+
|
41
44
|
if association_key_name.is_a?(Array)
|
42
45
|
query_constraints = Hash.new { |hsh, key| hsh[key] = Set.new }
|
43
46
|
|
@@ -1050,7 +1050,7 @@ module ActiveRecord
|
|
1050
1050
|
# query per addressable type.
|
1051
1051
|
# For example, if all the addressables are either of class Person or Company, then a total
|
1052
1052
|
# of 3 queries will be executed. The list of addressable types to load is determined on
|
1053
|
-
# the back of the addresses loaded. This is not supported if Active Record has to
|
1053
|
+
# the back of the addresses loaded. This is not supported if Active Record has to fall back
|
1054
1054
|
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
|
1055
1055
|
# The reason is that the parent model's type is a column value so its corresponding table
|
1056
1056
|
# name cannot be put in the +FROM+/+JOIN+ clauses of that query.
|
@@ -1339,7 +1339,7 @@ module ActiveRecord
|
|
1339
1339
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1340
1340
|
# An empty Relation is returned if none are found.
|
1341
1341
|
#
|
1342
|
-
#
|
1342
|
+
# ==== Example
|
1343
1343
|
#
|
1344
1344
|
# class Firm < ActiveRecord::Base
|
1345
1345
|
# has_many :clients
|
@@ -1369,7 +1369,7 @@ module ActiveRecord
|
|
1369
1369
|
#
|
1370
1370
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1371
1371
|
#
|
1372
|
-
#
|
1372
|
+
# ==== Scopes
|
1373
1373
|
#
|
1374
1374
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1375
1375
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1380,7 +1380,7 @@ module ActiveRecord
|
|
1380
1380
|
# has_many :employees, -> { joins(:address) }
|
1381
1381
|
# has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
|
1382
1382
|
#
|
1383
|
-
#
|
1383
|
+
# ==== Extensions
|
1384
1384
|
#
|
1385
1385
|
# The +extension+ argument allows you to pass a block into a has_many
|
1386
1386
|
# association. This is useful for adding new finders, creators, and other
|
@@ -1394,7 +1394,7 @@ module ActiveRecord
|
|
1394
1394
|
# end
|
1395
1395
|
# end
|
1396
1396
|
#
|
1397
|
-
#
|
1397
|
+
# ==== Options
|
1398
1398
|
# [+:class_name+]
|
1399
1399
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1400
1400
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
@@ -1556,7 +1556,7 @@ module ActiveRecord
|
|
1556
1556
|
# [<tt>reset_association</tt>]
|
1557
1557
|
# Unloads the associated object. The next access will query it from the database.
|
1558
1558
|
#
|
1559
|
-
#
|
1559
|
+
# ==== Example
|
1560
1560
|
#
|
1561
1561
|
# class Account < ActiveRecord::Base
|
1562
1562
|
# has_one :beneficiary
|
@@ -1575,7 +1575,7 @@ module ActiveRecord
|
|
1575
1575
|
# account.reload_beneficiary
|
1576
1576
|
# account.reset_beneficiary
|
1577
1577
|
#
|
1578
|
-
#
|
1578
|
+
# ==== Scopes
|
1579
1579
|
#
|
1580
1580
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1581
1581
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1586,7 +1586,7 @@ module ActiveRecord
|
|
1586
1586
|
# has_one :employer, -> { joins(:company) }
|
1587
1587
|
# has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
|
1588
1588
|
#
|
1589
|
-
#
|
1589
|
+
# ==== Options
|
1590
1590
|
#
|
1591
1591
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1592
1592
|
#
|
@@ -1745,7 +1745,7 @@ module ActiveRecord
|
|
1745
1745
|
# [<tt>association_previously_changed?</tt>]
|
1746
1746
|
# Returns true if the previous save updated the association to reference a new associate object.
|
1747
1747
|
#
|
1748
|
-
#
|
1748
|
+
# ==== Example
|
1749
1749
|
#
|
1750
1750
|
# class Post < ActiveRecord::Base
|
1751
1751
|
# belongs_to :author
|
@@ -1766,7 +1766,7 @@ module ActiveRecord
|
|
1766
1766
|
# post.author_changed?
|
1767
1767
|
# post.author_previously_changed?
|
1768
1768
|
#
|
1769
|
-
#
|
1769
|
+
# ==== Scopes
|
1770
1770
|
#
|
1771
1771
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1772
1772
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1777,7 +1777,7 @@ module ActiveRecord
|
|
1777
1777
|
# belongs_to :user, -> { joins(:friends) }
|
1778
1778
|
# belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
|
1779
1779
|
#
|
1780
|
-
#
|
1780
|
+
# ==== Options
|
1781
1781
|
#
|
1782
1782
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1783
1783
|
#
|
@@ -1964,7 +1964,7 @@ module ActiveRecord
|
|
1964
1964
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1965
1965
|
# An empty Relation is returned if none are found.
|
1966
1966
|
#
|
1967
|
-
#
|
1967
|
+
# ==== Example
|
1968
1968
|
#
|
1969
1969
|
# class Developer < ActiveRecord::Base
|
1970
1970
|
# has_and_belongs_to_many :projects
|
@@ -1993,7 +1993,7 @@ module ActiveRecord
|
|
1993
1993
|
#
|
1994
1994
|
# The declaration may include an +options+ hash to specialize the behavior of the association.
|
1995
1995
|
#
|
1996
|
-
#
|
1996
|
+
# ==== Scopes
|
1997
1997
|
#
|
1998
1998
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1999
1999
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -2005,7 +2005,7 @@ module ActiveRecord
|
|
2005
2005
|
# where("default_category = ?", post.default_category)
|
2006
2006
|
# }
|
2007
2007
|
#
|
2008
|
-
#
|
2008
|
+
# ==== Extensions
|
2009
2009
|
#
|
2010
2010
|
# The +extension+ argument allows you to pass a block into a
|
2011
2011
|
# has_and_belongs_to_many association. This is useful for adding new
|
@@ -2020,7 +2020,7 @@ module ActiveRecord
|
|
2020
2020
|
# end
|
2021
2021
|
# end
|
2022
2022
|
#
|
2023
|
-
#
|
2023
|
+
# ==== Options
|
2024
2024
|
#
|
2025
2025
|
# [+:class_name+]
|
2026
2026
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
# class Person < ActiveRecord::Base
|
15
15
|
# end
|
16
16
|
#
|
17
|
-
# person = Person.create(name: "
|
17
|
+
# person = Person.create(name: "Allison")
|
18
18
|
# person.changed? # => false
|
19
19
|
#
|
20
20
|
# Change the name:
|
@@ -76,11 +76,13 @@ module ActiveRecord
|
|
76
76
|
#
|
77
77
|
# ==== Options
|
78
78
|
#
|
79
|
-
# +from+
|
80
|
-
#
|
79
|
+
# [+from+]
|
80
|
+
# When specified, this method will return false unless the original
|
81
|
+
# value is equal to the given value.
|
81
82
|
#
|
82
|
-
# +to+
|
83
|
-
#
|
83
|
+
# [+to+]
|
84
|
+
# When specified, this method will return false unless the value will be
|
85
|
+
# changed to the given value.
|
84
86
|
def saved_change_to_attribute?(attr_name, **options)
|
85
87
|
mutations_before_last_save.changed?(attr_name.to_s, **options)
|
86
88
|
end
|
@@ -126,11 +128,13 @@ module ActiveRecord
|
|
126
128
|
#
|
127
129
|
# ==== Options
|
128
130
|
#
|
129
|
-
# +from+
|
130
|
-
#
|
131
|
+
# [+from+]
|
132
|
+
# When specified, this method will return false unless the original
|
133
|
+
# value is equal to the given value.
|
131
134
|
#
|
132
|
-
# +to+
|
133
|
-
#
|
135
|
+
# [+to+]
|
136
|
+
# When specified, this method will return false unless the value will be
|
137
|
+
# changed to the given value.
|
134
138
|
def will_save_change_to_attribute?(attr_name, **options)
|
135
139
|
mutations_from_database.changed?(attr_name.to_s, **options)
|
136
140
|
end
|
@@ -34,7 +34,7 @@ module ActiveRecord
|
|
34
34
|
Base.private_instance_methods -
|
35
35
|
Base.superclass.instance_methods -
|
36
36
|
Base.superclass.private_instance_methods +
|
37
|
-
%i[__id__ dup freeze frozen? hash
|
37
|
+
%i[__id__ dup freeze frozen? hash class clone]
|
38
38
|
).map { |m| -m.to_s }.to_set.freeze
|
39
39
|
end
|
40
40
|
end
|
@@ -241,8 +241,8 @@ module ActiveRecord
|
|
241
241
|
#
|
242
242
|
# config.active_record.run_after_transaction_callbacks_in_order_defined = false
|
243
243
|
#
|
244
|
-
#
|
245
|
-
# are defined, just like the example above.
|
244
|
+
# When set to +true+ (the default from \Rails 7.1), callbacks are executed in the order they
|
245
|
+
# are defined, just like the example above. When set to +false+, the order is reversed, so
|
246
246
|
# +do_something_else+ is executed before +log_children+.
|
247
247
|
#
|
248
248
|
# == \Transactions
|
@@ -58,12 +58,10 @@ module ActiveRecord
|
|
58
58
|
# Connections can be obtained and used from a connection pool in several
|
59
59
|
# ways:
|
60
60
|
#
|
61
|
-
# 1. Simply use {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling.connection]
|
62
|
-
#
|
63
|
-
# earlier (pre-connection-pooling). Eventually, when you're done with
|
64
|
-
# the connection(s) and wish it to be returned to the pool, you call
|
61
|
+
# 1. Simply use {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling.connection].
|
62
|
+
# When you're done with the connection(s) and wish it to be returned to the pool, you call
|
65
63
|
# {ActiveRecord::Base.connection_handler.clear_active_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_active_connections!].
|
66
|
-
# This
|
64
|
+
# This is the default behavior for Active Record when used in conjunction with
|
67
65
|
# Action Pack's request handling cycle.
|
68
66
|
# 2. Manually check out a connection from the pool with
|
69
67
|
# {ActiveRecord::Base.connection_pool.checkout}[rdoc-ref:#checkout]. You are responsible for
|
@@ -465,8 +463,7 @@ module ActiveRecord
|
|
465
463
|
@available.num_waiting
|
466
464
|
end
|
467
465
|
|
468
|
-
#
|
469
|
-
# Example:
|
466
|
+
# Returns the connection pool's usage statistic.
|
470
467
|
#
|
471
468
|
# ActiveRecord::Base.connection_pool.stat # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
|
472
469
|
def stat
|
@@ -658,7 +655,13 @@ module ActiveRecord
|
|
658
655
|
conn
|
659
656
|
else
|
660
657
|
reap
|
661
|
-
|
658
|
+
# Retry after reaping, which may return an available connection,
|
659
|
+
# remove an inactive connection, or both
|
660
|
+
if conn = @available.poll || try_to_checkout_new_connection
|
661
|
+
conn
|
662
|
+
else
|
663
|
+
@available.poll(checkout_timeout)
|
664
|
+
end
|
662
665
|
end
|
663
666
|
end
|
664
667
|
|
@@ -189,8 +189,10 @@ module ActiveRecord
|
|
189
189
|
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
|
190
190
|
sql, binds = to_sql_and_binds(arel, binds)
|
191
191
|
value = exec_insert(sql, name, binds, pk, sequence_name, returning: returning)
|
192
|
-
|
193
|
-
|
192
|
+
|
193
|
+
return returning_column_values(value) unless returning.nil?
|
194
|
+
|
195
|
+
id_value || last_inserted_id(value)
|
194
196
|
end
|
195
197
|
alias create insert
|
196
198
|
|
@@ -106,7 +106,8 @@ module ActiveRecord
|
|
106
106
|
sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
|
107
107
|
|
108
108
|
if async
|
109
|
-
lookup_sql_cache(sql, name, binds) || super(sql, name, binds, preparable: preparable, async: async)
|
109
|
+
result = lookup_sql_cache(sql, name, binds) || super(sql, name, binds, preparable: preparable, async: async)
|
110
|
+
FutureResult::Complete.new(result)
|
110
111
|
else
|
111
112
|
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable, async: async) }
|
112
113
|
end
|
@@ -970,7 +970,11 @@ module ActiveRecord
|
|
970
970
|
# If +allow_retry+ is true, a connection-related exception will
|
971
971
|
# cause an automatic reconnect and re-run of the block, up to
|
972
972
|
# the connection's configured +connection_retries+ setting
|
973
|
-
# and the configured +retry_deadline+ limit.
|
973
|
+
# and the configured +retry_deadline+ limit. (Note that when
|
974
|
+
# +allow_retry+ is true, it's possible to return without having marked
|
975
|
+
# the connection as verified. If the block is guaranteed to exercise the
|
976
|
+
# connection, consider calling `verified!` to avoid needless
|
977
|
+
# verification queries in subsequent calls.)
|
974
978
|
#
|
975
979
|
# If +materialize_transactions+ is false, the block will be run without
|
976
980
|
# ensuring virtual transactions have been materialized in the DB
|
@@ -1021,9 +1025,7 @@ module ActiveRecord
|
|
1021
1025
|
end
|
1022
1026
|
|
1023
1027
|
begin
|
1024
|
-
|
1025
|
-
@verified = true
|
1026
|
-
result
|
1028
|
+
yield @raw_connection
|
1027
1029
|
rescue => original_exception
|
1028
1030
|
translated_exception = translate_exception_class(original_exception, nil, nil)
|
1029
1031
|
invalidate_transaction(translated_exception)
|
@@ -1058,6 +1060,13 @@ module ActiveRecord
|
|
1058
1060
|
end
|
1059
1061
|
end
|
1060
1062
|
|
1063
|
+
# Mark the connection as verified. Call this inside a
|
1064
|
+
# `with_raw_connection` block only when the block is guaranteed to
|
1065
|
+
# exercise the raw connection.
|
1066
|
+
def verified!
|
1067
|
+
@verified = true
|
1068
|
+
end
|
1069
|
+
|
1061
1070
|
def retryable_connection_error?(exception)
|
1062
1071
|
exception.is_a?(ConnectionNotEstablished) || exception.is_a?(ConnectionFailed)
|
1063
1072
|
end
|
@@ -98,6 +98,7 @@ module ActiveRecord
|
|
98
98
|
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
|
99
99
|
sync_timezone_changes(conn)
|
100
100
|
result = conn.query(sql)
|
101
|
+
verified!
|
101
102
|
handle_warnings(sql)
|
102
103
|
result
|
103
104
|
end
|
@@ -126,6 +127,8 @@ module ActiveRecord
|
|
126
127
|
result = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
127
128
|
stmt.execute(*type_casted_binds)
|
128
129
|
end
|
130
|
+
verified!
|
131
|
+
result
|
129
132
|
rescue ::Mysql2::Error => e
|
130
133
|
if cache_stmt
|
131
134
|
@statements.delete(sql)
|
@@ -16,7 +16,9 @@ module ActiveRecord
|
|
16
16
|
|
17
17
|
log(sql, name) do
|
18
18
|
with_raw_connection do |conn|
|
19
|
-
conn.async_exec(sql).map_types!(@type_map_for_results).values
|
19
|
+
result = conn.async_exec(sql).map_types!(@type_map_for_results).values
|
20
|
+
verified!
|
21
|
+
result
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -51,6 +53,7 @@ module ActiveRecord
|
|
51
53
|
log(sql, name, async: async) do
|
52
54
|
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
|
53
55
|
result = conn.async_exec(sql)
|
56
|
+
verified!
|
54
57
|
handle_warnings(result)
|
55
58
|
result
|
56
59
|
end
|
@@ -27,9 +27,10 @@ module ActiveRecord
|
|
27
27
|
value = value.sub(/^\((.+)\)$/, '-\1') # (4)
|
28
28
|
case value
|
29
29
|
when /^-?\D*+[\d,]+\.\d{2}$/ # (1)
|
30
|
-
value.
|
30
|
+
value.delete!("^-0-9.")
|
31
31
|
when /^-?\D*+[\d.]+,\d{2}$/ # (2)
|
32
|
-
value.
|
32
|
+
value.delete!("^-0-9,")
|
33
|
+
value.tr!(",", ".")
|
33
34
|
end
|
34
35
|
|
35
36
|
super(value)
|
@@ -341,7 +341,7 @@ module ActiveRecord
|
|
341
341
|
JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid)
|
342
342
|
WHERE t.oid = #{quote(quote_table_name(table))}::regclass
|
343
343
|
AND cons.contype = 'p'
|
344
|
-
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate'
|
344
|
+
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate|gen_random_uuid'
|
345
345
|
SQL
|
346
346
|
end
|
347
347
|
|
@@ -385,11 +385,18 @@ module ActiveRecord
|
|
385
385
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
|
386
386
|
pk, seq = pk_and_sequence_for(new_name)
|
387
387
|
if pk
|
388
|
-
|
389
|
-
|
388
|
+
# PostgreSQL automatically creates an index for PRIMARY KEY with name consisting of
|
389
|
+
# truncated table name and "_pkey" suffix fitting into max_identifier_length number of characters.
|
390
|
+
max_pkey_prefix = max_identifier_length - "_pkey".size
|
391
|
+
idx = "#{table_name[0, max_pkey_prefix]}_pkey"
|
392
|
+
new_idx = "#{new_name[0, max_pkey_prefix]}_pkey"
|
390
393
|
execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
|
391
|
-
|
392
|
-
|
394
|
+
|
395
|
+
# PostgreSQL automatically creates a sequence for PRIMARY KEY with name consisting of
|
396
|
+
# truncated table name and "#{primary_key}_seq" suffix fitting into max_identifier_length number of characters.
|
397
|
+
max_seq_prefix = max_identifier_length - "_#{pk}_seq".size
|
398
|
+
if seq && seq.identifier == "#{table_name[0, max_seq_prefix]}_#{pk}_seq"
|
399
|
+
new_seq = "#{new_name[0, max_seq_prefix]}_#{pk}_seq"
|
393
400
|
execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
|
394
401
|
end
|
395
402
|
end
|