activerecord 7.2.0 → 7.2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +196 -0
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +5 -5
- data/lib/active_record/associations.rb +28 -16
- data/lib/active_record/attribute_assignment.rb +9 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +49 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +45 -16
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -3
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
- data/lib/active_record/core.rb +41 -9
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +1 -1
- data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
- data/lib/active_record/encryption/encryptor.rb +1 -1
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +8 -0
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/model_schema.rb +5 -2
- data/lib/active_record/nested_attributes.rb +13 -2
- data/lib/active_record/query_cache.rb +4 -5
- data/lib/active_record/query_logs.rb +1 -1
- data/lib/active_record/railtie.rb +7 -12
- data/lib/active_record/reflection.rb +15 -8
- data/lib/active_record/relation/batches.rb +4 -4
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +39 -24
- data/lib/active_record/scoping/named.rb +1 -0
- data/lib/active_record/tasks/database_tasks.rb +12 -1
- data/lib/active_record/testing/query_assertions.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +1 -0
- data/lib/arel/visitors/sqlite.rb +25 -0
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fa184c958d89b0bfbb95921e93d9dee4396b91ea57216f69cdaa0907fca900f
|
4
|
+
data.tar.gz: bab6a4f88acae3ad29b12d2d84229ad386acd8bca6e617804285b8d7534ea1ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91cf7ccf875cbd0a5c687e354edd6f4338d9b7edcc900952f9b4fef3843c03488abcfba7c2fd4a001954c9891283c232cb9719ad5f3e9383f23656c04930ff2f
|
7
|
+
data.tar.gz: 4577e8f11d54b506f3d0fe841a25a1bbb7df529f22f51f08f0c70ec097098e80adab1d95f24f7048879ce5eb3aff6d330c124ad34c6667ebfdcc1c5823832821
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,199 @@
|
|
1
|
+
## Rails 7.2.2.1 (December 10, 2024) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 7.2.2 (October 30, 2024) ##
|
7
|
+
|
8
|
+
* Fix support for `query_cache: false` in `database.yml`.
|
9
|
+
|
10
|
+
`query_cache: false` would no longer entirely disable the Active Record query cache.
|
11
|
+
|
12
|
+
*zzak*
|
13
|
+
|
14
|
+
* Set `.attributes_for_inspect` to `:all` by default.
|
15
|
+
|
16
|
+
For new applications it is set to `[:id]` in config/environment/production.rb.
|
17
|
+
|
18
|
+
In the console all the attributes are always shown.
|
19
|
+
|
20
|
+
*Andrew Novoselac*
|
21
|
+
|
22
|
+
* `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
|
23
|
+
|
24
|
+
*Kazuma Watanabe*
|
25
|
+
|
26
|
+
* Fix marshalling of unsaved associated records in 7.1 format.
|
27
|
+
|
28
|
+
The 7.1 format would only marshal associated records if the association was loaded.
|
29
|
+
But associations that would only contain unsaved records would be skipped.
|
30
|
+
|
31
|
+
*Jean Boussier*
|
32
|
+
|
33
|
+
* Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
|
34
|
+
|
35
|
+
*David Stosik*
|
36
|
+
|
37
|
+
* Allow to save records with polymorphic join tables that have `inverse_of`
|
38
|
+
specified.
|
39
|
+
|
40
|
+
*Markus Doits*
|
41
|
+
|
42
|
+
* Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
|
43
|
+
|
44
|
+
*Joshua Young*
|
45
|
+
|
46
|
+
* Fix `dependent: :destroy` for bi-directional has one through association.
|
47
|
+
|
48
|
+
Fixes #50948.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
class Left < ActiveRecord::Base
|
52
|
+
has_one :middle, dependent: :destroy
|
53
|
+
has_one :right, through: :middle
|
54
|
+
end
|
55
|
+
|
56
|
+
class Middle < ActiveRecord::Base
|
57
|
+
belongs_to :left, dependent: :destroy
|
58
|
+
belongs_to :right, dependent: :destroy
|
59
|
+
end
|
60
|
+
|
61
|
+
class Right < ActiveRecord::Base
|
62
|
+
has_one :middle, dependent: :destroy
|
63
|
+
has_one :left, through: :middle
|
64
|
+
end
|
65
|
+
```
|
66
|
+
In the above example `left.destroy` wouldn't destroy its associated `Right`
|
67
|
+
record.
|
68
|
+
|
69
|
+
*Andy Stewart*
|
70
|
+
|
71
|
+
* Properly handle lazily pinned connection pools.
|
72
|
+
|
73
|
+
Fixes #53147.
|
74
|
+
|
75
|
+
When using transactional fixtures with system tests to similar tools
|
76
|
+
such as capybara, it could happen that a connection end up pinned by the
|
77
|
+
server thread rather than the test thread, causing
|
78
|
+
`"Cannot expire connection, it is owned by a different thread"` errors.
|
79
|
+
|
80
|
+
*Jean Boussier*
|
81
|
+
|
82
|
+
* Fix `ActiveRecord::Base.with` to accept more than two sub queries.
|
83
|
+
|
84
|
+
Fixes #53110.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
|
88
|
+
undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
|
89
|
+
```
|
90
|
+
|
91
|
+
The above now works as expected.
|
92
|
+
|
93
|
+
*fatkodima*
|
94
|
+
|
95
|
+
* Properly release pinned connections with non joinable connections.
|
96
|
+
|
97
|
+
Fixes #52973
|
98
|
+
|
99
|
+
When running system tests with transactional fixtures on, it could happen that
|
100
|
+
the connection leased by the Puma thread wouldn't be properly released back to the pool,
|
101
|
+
causing "Cannot expire connection, it is owned by a different thread" errors in later tests.
|
102
|
+
|
103
|
+
*Jean Boussier*
|
104
|
+
|
105
|
+
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
106
|
+
|
107
|
+
Fixes #52742
|
108
|
+
|
109
|
+
*Ryota Kitazawa*, *Takayuki Nagatomi*
|
110
|
+
|
111
|
+
* Fix an issue where `.left_outer_joins` used with multiple associations that have
|
112
|
+
the same child association but different parents does not join all parents.
|
113
|
+
|
114
|
+
Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
|
115
|
+
|
116
|
+
Now it will correctly join both parents.
|
117
|
+
|
118
|
+
Fixes #41498.
|
119
|
+
|
120
|
+
*Garrett Blehm*
|
121
|
+
|
122
|
+
* Ensure `ActiveRecord::Encryption.config` is always ready before access.
|
123
|
+
|
124
|
+
Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
|
125
|
+
was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
|
126
|
+
`ActiveRecord::Base` was loaded would give incorrect results.
|
127
|
+
|
128
|
+
`ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
|
129
|
+
soon as needed.
|
130
|
+
|
131
|
+
When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
|
132
|
+
`ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
|
133
|
+
before any use of `ActiveRecord::Base`.
|
134
|
+
|
135
|
+
*Maxime Réty*
|
136
|
+
|
137
|
+
* Add `TimeZoneConverter#==` method, so objects will be properly compared by
|
138
|
+
their type, scale, limit & precision.
|
139
|
+
|
140
|
+
Address #52699.
|
141
|
+
|
142
|
+
*Ruy Rocha*
|
143
|
+
|
144
|
+
|
145
|
+
## Rails 7.2.1.2 (October 23, 2024) ##
|
146
|
+
|
147
|
+
* No changes.
|
148
|
+
|
149
|
+
|
150
|
+
## Rails 7.2.1.1 (October 15, 2024) ##
|
151
|
+
|
152
|
+
* No changes.
|
153
|
+
|
154
|
+
|
155
|
+
## Rails 7.2.1 (August 22, 2024) ##
|
156
|
+
|
157
|
+
* Fix detection for `enum` columns with parallelized tests and PostgreSQL.
|
158
|
+
|
159
|
+
*Rafael Mendonça França*
|
160
|
+
|
161
|
+
* Allow to eager load nested nil associations.
|
162
|
+
|
163
|
+
*fatkodima*
|
164
|
+
|
165
|
+
* Fix swallowing ignore order warning when batching using `BatchEnumerator`.
|
166
|
+
|
167
|
+
*fatkodima*
|
168
|
+
|
169
|
+
* Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
|
170
|
+
|
171
|
+
*Jean Boussier*
|
172
|
+
|
173
|
+
* Restore inferred association class with the same modularized name.
|
174
|
+
|
175
|
+
*Justin Ko*
|
176
|
+
|
177
|
+
* Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
|
178
|
+
|
179
|
+
*Jean Boussier*
|
180
|
+
|
181
|
+
* Check invalid `enum` options for the new syntax.
|
182
|
+
|
183
|
+
The options using `_` prefix in the old syntax are invalid in the new syntax.
|
184
|
+
|
185
|
+
*Rafael Mendonça França*
|
186
|
+
|
187
|
+
* Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
|
188
|
+
actual cast type.
|
189
|
+
|
190
|
+
*Vasiliy Ermolovich*
|
191
|
+
|
192
|
+
* Fix `create_table` with `:auto_increment` option for MySQL adapter.
|
193
|
+
|
194
|
+
*fatkodima*
|
195
|
+
|
196
|
+
|
1
197
|
## Rails 7.2.0 (August 09, 2024) ##
|
2
198
|
|
3
199
|
* Handle commas in Sqlite3 default function definitions.
|
@@ -93,7 +93,13 @@ module ActiveRecord
|
|
93
93
|
@through_scope = scope
|
94
94
|
record = super
|
95
95
|
|
96
|
-
inverse =
|
96
|
+
inverse =
|
97
|
+
if source_reflection.polymorphic?
|
98
|
+
source_reflection.polymorphic_inverse_of(record.class)
|
99
|
+
else
|
100
|
+
source_reflection.inverse_of
|
101
|
+
end
|
102
|
+
|
97
103
|
if inverse
|
98
104
|
if inverse.collection?
|
99
105
|
record.send(inverse.name) << build_through_record(record)
|
@@ -25,8 +25,9 @@ module ActiveRecord
|
|
25
25
|
joins = []
|
26
26
|
chain = []
|
27
27
|
|
28
|
-
reflection.chain
|
29
|
-
|
28
|
+
reflection_chain = reflection.chain
|
29
|
+
reflection_chain.each_with_index do |reflection, index|
|
30
|
+
table, terminated = yield reflection, reflection_chain[index..]
|
30
31
|
@table ||= table
|
31
32
|
|
32
33
|
if terminated
|
@@ -61,7 +61,7 @@ module ActiveRecord
|
|
61
61
|
when Hash
|
62
62
|
associations.each do |k, v|
|
63
63
|
cache = hash[k] ||= {}
|
64
|
-
walk_tree v, cache
|
64
|
+
walk_tree v, cache if v
|
65
65
|
end
|
66
66
|
else
|
67
67
|
raise ConfigurationError, associations.inspect
|
@@ -190,12 +190,12 @@ module ActiveRecord
|
|
190
190
|
def make_constraints(parent, child, join_type)
|
191
191
|
foreign_table = parent.table
|
192
192
|
foreign_klass = parent.base_klass
|
193
|
-
child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker) do |reflection|
|
194
|
-
table, terminated = @joined_tables[
|
193
|
+
child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker) do |reflection, remaining_reflection_chain|
|
194
|
+
table, terminated = @joined_tables[remaining_reflection_chain]
|
195
195
|
root = reflection == child.reflection
|
196
196
|
|
197
197
|
if table && (!root || !terminated)
|
198
|
-
@joined_tables[
|
198
|
+
@joined_tables[remaining_reflection_chain] = [table, root] if root
|
199
199
|
next table, true
|
200
200
|
end
|
201
201
|
|
@@ -206,7 +206,7 @@ module ActiveRecord
|
|
206
206
|
root ? name : "#{name}_join"
|
207
207
|
end
|
208
208
|
|
209
|
-
@joined_tables[
|
209
|
+
@joined_tables[remaining_reflection_chain] ||= [table, root] if join_type == Arel::Nodes::OuterJoin
|
210
210
|
table
|
211
211
|
end.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
|
212
212
|
end
|
@@ -537,7 +537,7 @@ module ActiveRecord
|
|
537
537
|
# @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
|
538
538
|
# @group.avatars.delete(@group.avatars.last) # so would this
|
539
539
|
#
|
540
|
-
#
|
540
|
+
# === Setting Inverses
|
541
541
|
#
|
542
542
|
# If you are using a #belongs_to on the join model, it is a good idea to set the
|
543
543
|
# <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example
|
@@ -1199,8 +1199,11 @@ module ActiveRecord
|
|
1199
1199
|
# If you are going to modify the association (rather than just read from it), then it is
|
1200
1200
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1201
1201
|
# join model. This allows associated records to be built which will automatically create
|
1202
|
-
# the appropriate join model records when they are saved.
|
1203
|
-
#
|
1202
|
+
# the appropriate join model records when they are saved. See
|
1203
|
+
# {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
|
1204
|
+
# and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
|
1205
|
+
# more detail.
|
1206
|
+
#
|
1204
1207
|
# [+:disable_joins+]
|
1205
1208
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1206
1209
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
@@ -1229,7 +1232,8 @@ module ActiveRecord
|
|
1229
1232
|
# [+:inverse_of+]
|
1230
1233
|
# Specifies the name of the #belongs_to association on the associated object
|
1231
1234
|
# that is the inverse of this #has_many association.
|
1232
|
-
# See
|
1235
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1236
|
+
# for more detail.
|
1233
1237
|
# [+:extend+]
|
1234
1238
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
1235
1239
|
# Useful for defining methods on associations, especially when they should be shared between multiple
|
@@ -1270,10 +1274,12 @@ module ActiveRecord
|
|
1270
1274
|
Reflection.add_reflection self, name, reflection
|
1271
1275
|
end
|
1272
1276
|
|
1273
|
-
# Specifies a one-to-one association with another class. This method
|
1274
|
-
# if the other class contains the foreign key. If
|
1275
|
-
#
|
1276
|
-
#
|
1277
|
+
# Specifies a one-to-one association with another class. This method
|
1278
|
+
# should only be used if the other class contains the foreign key. If
|
1279
|
+
# the current class contains the foreign key, then you should use
|
1280
|
+
# #belongs_to instead. See {Is it a belongs_to or has_one
|
1281
|
+
# association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
|
1282
|
+
# for more detail on when to use #has_one and when to use #belongs_to.
|
1277
1283
|
#
|
1278
1284
|
# The following methods for retrieval and query of a single associated object will be added:
|
1279
1285
|
#
|
@@ -1388,8 +1394,10 @@ module ActiveRecord
|
|
1388
1394
|
# If you are going to modify the association (rather than just read from it), then it is
|
1389
1395
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1390
1396
|
# join model. This allows associated records to be built which will automatically create
|
1391
|
-
# the appropriate join model records when they are saved.
|
1392
|
-
#
|
1397
|
+
# the appropriate join model records when they are saved. See
|
1398
|
+
# {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
|
1399
|
+
# and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
|
1400
|
+
# more detail.
|
1393
1401
|
# [+:disable_joins+]
|
1394
1402
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1395
1403
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
@@ -1427,7 +1435,8 @@ module ActiveRecord
|
|
1427
1435
|
# [+:inverse_of+]
|
1428
1436
|
# Specifies the name of the #belongs_to association on the associated object
|
1429
1437
|
# that is the inverse of this #has_one association.
|
1430
|
-
# See
|
1438
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1439
|
+
# for more detail.
|
1431
1440
|
# [+:required+]
|
1432
1441
|
# When set to +true+, the association will also have its presence validated.
|
1433
1442
|
# This will validate the association itself, not the id. You can use
|
@@ -1461,10 +1470,12 @@ module ActiveRecord
|
|
1461
1470
|
Reflection.add_reflection self, name, reflection
|
1462
1471
|
end
|
1463
1472
|
|
1464
|
-
# Specifies a one-to-one association with another class. This method
|
1465
|
-
# if this class contains the foreign key. If the
|
1466
|
-
# then you should use #has_one
|
1467
|
-
#
|
1473
|
+
# Specifies a one-to-one association with another class. This method
|
1474
|
+
# should only be used if this class contains the foreign key. If the
|
1475
|
+
# other class contains the foreign key, then you should use #has_one
|
1476
|
+
# instead. See {Is it a belongs_to or has_one
|
1477
|
+
# association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
|
1478
|
+
# for more detail on when to use #has_one and when to use #belongs_to.
|
1468
1479
|
#
|
1469
1480
|
# Methods will be added for retrieval and query for a single associated object, for which
|
1470
1481
|
# this object holds an id:
|
@@ -1606,7 +1617,8 @@ module ActiveRecord
|
|
1606
1617
|
# [+:inverse_of+]
|
1607
1618
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1608
1619
|
# object that is the inverse of this #belongs_to association.
|
1609
|
-
# See
|
1620
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1621
|
+
# for more detail.
|
1610
1622
|
# [+:optional+]
|
1611
1623
|
# When set to +true+, the association will not have its presence validated.
|
1612
1624
|
# [+:required+]
|
@@ -4,21 +4,29 @@ module ActiveRecord
|
|
4
4
|
module AttributeAssignment
|
5
5
|
private
|
6
6
|
def _assign_attributes(attributes)
|
7
|
-
multi_parameter_attributes = nil
|
7
|
+
multi_parameter_attributes = nested_parameter_attributes = nil
|
8
8
|
|
9
9
|
attributes.each do |k, v|
|
10
10
|
key = k.to_s
|
11
11
|
|
12
12
|
if key.include?("(")
|
13
13
|
(multi_parameter_attributes ||= {})[key] = v
|
14
|
+
elsif v.is_a?(Hash)
|
15
|
+
(nested_parameter_attributes ||= {})[key] = v
|
14
16
|
else
|
15
17
|
_assign_attribute(key, v)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
assign_nested_parameter_attributes(nested_parameter_attributes) if nested_parameter_attributes
|
19
22
|
assign_multiparameter_attributes(multi_parameter_attributes) if multi_parameter_attributes
|
20
23
|
end
|
21
24
|
|
25
|
+
# Assign any deferred nested attributes after the base attributes have been set.
|
26
|
+
def assign_nested_parameter_attributes(pairs)
|
27
|
+
pairs.each { |k, v| _assign_attribute(k, v) }
|
28
|
+
end
|
29
|
+
|
22
30
|
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
|
23
31
|
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
|
24
32
|
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
|
@@ -25,15 +25,17 @@ module ActiveRecord
|
|
25
25
|
# column which this will persist to.
|
26
26
|
#
|
27
27
|
# +cast_type+ A symbol such as +:string+ or +:integer+, or a type object
|
28
|
-
# to be used for this attribute.
|
29
|
-
#
|
28
|
+
# to be used for this attribute. If this parameter is not passed, the previously
|
29
|
+
# defined type (if any) will be used.
|
30
|
+
# Otherwise, the type will be ActiveModel::Type::Value.
|
31
|
+
# See the examples below for more information about providing custom type objects.
|
30
32
|
#
|
31
33
|
# ==== Options
|
32
34
|
#
|
33
35
|
# The following options are accepted:
|
34
36
|
#
|
35
37
|
# +default+ The default value to use when no value is provided. If this option
|
36
|
-
# is not passed, the
|
38
|
+
# is not passed, the previously defined default value (if any) on the superclass or in the schema will be used.
|
37
39
|
# Otherwise, the default will be +nil+.
|
38
40
|
#
|
39
41
|
# +array+ (PostgreSQL only) specifies that the type should be an array (see the
|
@@ -210,8 +212,7 @@ module ActiveRecord
|
|
210
212
|
#--
|
211
213
|
# Implemented by ActiveModel::AttributeRegistration#attribute.
|
212
214
|
|
213
|
-
# This
|
214
|
-
# accepts type objects, and will do its work immediately instead of
|
215
|
+
# This API only accepts type objects, and will do its work immediately instead of
|
215
216
|
# waiting for the schema to load. While this method
|
216
217
|
# is provided so it can be used by plugin authors, application code
|
217
218
|
# should probably use ClassMethods#attribute.
|
@@ -418,7 +418,7 @@ module ActiveRecord
|
|
418
418
|
|
419
419
|
def destroy # :nodoc:
|
420
420
|
@_destroy_callback_already_called ||= false
|
421
|
-
return if @_destroy_callback_already_called
|
421
|
+
return true if @_destroy_callback_already_called
|
422
422
|
@_destroy_callback_already_called = true
|
423
423
|
_run_destroy_callbacks { super }
|
424
424
|
rescue RecordNotDestroyed => e
|
@@ -118,6 +118,27 @@ module ActiveRecord
|
|
118
118
|
# * private methods that require being called in a +synchronize+ blocks
|
119
119
|
# are now explicitly documented
|
120
120
|
class ConnectionPool
|
121
|
+
class WeakThreadKeyMap # :nodoc:
|
122
|
+
# FIXME: On 3.3 we could use ObjectSpace::WeakKeyMap
|
123
|
+
# but it currently cause GC crashes: https://github.com/byroot/rails/pull/3
|
124
|
+
def initialize
|
125
|
+
@map = {}
|
126
|
+
end
|
127
|
+
|
128
|
+
def clear
|
129
|
+
@map.clear
|
130
|
+
end
|
131
|
+
|
132
|
+
def [](key)
|
133
|
+
@map[key]
|
134
|
+
end
|
135
|
+
|
136
|
+
def []=(key, value)
|
137
|
+
@map.select! { |c, _| c.alive? }
|
138
|
+
@map[key] = value
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
121
142
|
class Lease # :nodoc:
|
122
143
|
attr_accessor :connection, :sticky
|
123
144
|
|
@@ -145,48 +166,9 @@ module ActiveRecord
|
|
145
166
|
end
|
146
167
|
|
147
168
|
class LeaseRegistry # :nodoc:
|
148
|
-
if ObjectSpace.const_defined?(:WeakKeyMap) # RUBY_VERSION >= 3.3
|
149
|
-
WeakKeyMap = ::ObjectSpace::WeakKeyMap # :nodoc:
|
150
|
-
else
|
151
|
-
class WeakKeyMap # :nodoc:
|
152
|
-
def initialize
|
153
|
-
@map = ObjectSpace::WeakMap.new
|
154
|
-
@values = nil
|
155
|
-
@size = 0
|
156
|
-
end
|
157
|
-
|
158
|
-
alias_method :clear, :initialize
|
159
|
-
|
160
|
-
def [](key)
|
161
|
-
prune if @map.size != @size
|
162
|
-
@map[key]
|
163
|
-
end
|
164
|
-
|
165
|
-
def []=(key, value)
|
166
|
-
@map[key] = value
|
167
|
-
prune if @map.size != @size
|
168
|
-
value
|
169
|
-
end
|
170
|
-
|
171
|
-
def delete(key)
|
172
|
-
if value = self[key]
|
173
|
-
self[key] = nil
|
174
|
-
prune
|
175
|
-
end
|
176
|
-
value
|
177
|
-
end
|
178
|
-
|
179
|
-
private
|
180
|
-
def prune(force = false)
|
181
|
-
@values = @map.values
|
182
|
-
@size = @map.size
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
169
|
def initialize
|
188
170
|
@mutex = Mutex.new
|
189
|
-
@map =
|
171
|
+
@map = WeakThreadKeyMap.new
|
190
172
|
end
|
191
173
|
|
192
174
|
def [](context)
|
@@ -197,11 +179,36 @@ module ActiveRecord
|
|
197
179
|
|
198
180
|
def clear
|
199
181
|
@mutex.synchronize do
|
200
|
-
@map
|
182
|
+
@map.clear
|
201
183
|
end
|
202
184
|
end
|
203
185
|
end
|
204
186
|
|
187
|
+
module ExecutorHooks # :nodoc:
|
188
|
+
class << self
|
189
|
+
def run
|
190
|
+
# noop
|
191
|
+
end
|
192
|
+
|
193
|
+
def complete(_)
|
194
|
+
ActiveRecord::Base.connection_handler.each_connection_pool do |pool|
|
195
|
+
if (connection = pool.active_connection?)
|
196
|
+
transaction = connection.current_transaction
|
197
|
+
if transaction.closed? || !transaction.joinable?
|
198
|
+
pool.release_connection
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
class << self
|
207
|
+
def install_executor_hooks(executor = ActiveSupport::Executor)
|
208
|
+
executor.register_hook(ExecutorHooks)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
205
212
|
include MonitorMixin
|
206
213
|
prepend QueryCache::ConnectionPoolConfiguration
|
207
214
|
include ConnectionAdapters::AbstractPool
|
@@ -351,6 +358,7 @@ module ActiveRecord
|
|
351
358
|
end
|
352
359
|
|
353
360
|
if @pinned_connection.nil?
|
361
|
+
connection.steal!
|
354
362
|
connection.lock_thread = nil
|
355
363
|
checkin(connection)
|
356
364
|
end
|
@@ -630,8 +638,6 @@ module ActiveRecord
|
|
630
638
|
remove conn
|
631
639
|
end
|
632
640
|
end
|
633
|
-
|
634
|
-
prune_thread_cache
|
635
641
|
end
|
636
642
|
|
637
643
|
# Disconnect all connections that have been idle for at least
|