activerecord 7.0.5 → 7.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -1
- data/README.rdoc +2 -2
- data/lib/active_record/autosave_association.rb +9 -5
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +32 -18
- data/lib/active_record/persistence.rb +4 -4
- data/lib/active_record/reflection.rb +8 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
- data/lib/active_record/relation/query_methods.rb +10 -2
- data/lib/active_record/result.rb +6 -4
- data/lib/active_record/table_metadata.rb +5 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fc8d9f64d2ef73d31d77f9bb3ab1792606a33e541bd28a08566304fc81d5d07
|
4
|
+
data.tar.gz: 7e4b61e90c14d831d3b888859ba713dd5cbb35d1554225aec1c483ee8857aee9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faf9806425e9a75ecde61e1b84bc6eec459cd18895684200701394315b5e7bff69487a4baab67482a80baa1f5e2fcf81021781ceb81cba39f7fbc75bfe7200d4
|
7
|
+
data.tar.gz: b940c37c5f10f000f37ba68eb9be3aa2ae5dabc329a16979587dd1cd75ba464976cefccc437ba9958eb444a35f9303214d7e5f0d06d37b4e45809337977d8829
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,58 @@
|
|
1
|
+
## Rails 7.0.6 (June 29, 2023) ##
|
2
|
+
|
3
|
+
* Fix autosave associations with validations added on `:base` of the associated objects.
|
4
|
+
|
5
|
+
*fatkodima*
|
6
|
+
|
7
|
+
* Fix result with anonymous PostgreSQL columns of different type from json.
|
8
|
+
|
9
|
+
*Oleksandr Avoiants*
|
10
|
+
|
11
|
+
* Preserve timestamp when setting an `ActiveSupport::TimeWithZone` value to `timestamptz` attribute.
|
12
|
+
|
13
|
+
*fatkodima*
|
14
|
+
|
15
|
+
* Fix where on association with has_one/has_many polymorphic relations.
|
16
|
+
|
17
|
+
Before:
|
18
|
+
```ruby
|
19
|
+
Treasure.where(price_estimates: PriceEstimate.all)
|
20
|
+
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
|
21
|
+
```
|
22
|
+
|
23
|
+
Later:
|
24
|
+
```ruby
|
25
|
+
Treasure.where(price_estimates: PriceEstimate.all)
|
26
|
+
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
|
27
|
+
```
|
28
|
+
|
29
|
+
*Lázaro Nixon*
|
30
|
+
|
31
|
+
* Fix decrementing counter caches on optimistically locked record deletion
|
32
|
+
|
33
|
+
*fatkodima*
|
34
|
+
|
35
|
+
* Ensure binary-destined values have binary encoding during type cast.
|
36
|
+
|
37
|
+
*Matthew Draper*
|
38
|
+
|
39
|
+
* Preserve existing column default functions when altering table in SQLite.
|
40
|
+
|
41
|
+
*fatkodima*
|
42
|
+
|
43
|
+
* Remove table alias added when using `where.missing` or `where.associated`.
|
44
|
+
|
45
|
+
*fatkodima*
|
46
|
+
|
47
|
+
* Fix `Enumerable#in_order_of` to only flatten first level to preserve nesting.
|
48
|
+
|
49
|
+
*Miha Rekar*
|
50
|
+
|
51
|
+
|
52
|
+
## Rails 7.0.5.1 (June 26, 2023) ##
|
53
|
+
|
54
|
+
* No changes.
|
55
|
+
|
1
56
|
## Rails 7.0.5 (May 24, 2023) ##
|
2
57
|
|
3
58
|
* Type cast `#attribute_changed?` `:from` and `:to` options.
|
@@ -76,7 +131,7 @@
|
|
76
131
|
|
77
132
|
*Shota Toguchi*, *Yusaku Ono*
|
78
133
|
|
79
|
-
*
|
134
|
+
* Fix erroneous nil default precision on virtual datetime columns.
|
80
135
|
|
81
136
|
Prior to this change, virtual datetime columns did not have the same
|
82
137
|
default precision as regular datetime columns, resulting in the following
|
data/README.rdoc
CHANGED
@@ -192,7 +192,7 @@ The latest version of Active Record can be installed with RubyGems:
|
|
192
192
|
|
193
193
|
$ gem install activerecord
|
194
194
|
|
195
|
-
Source code can be downloaded as part of the Rails project on GitHub:
|
195
|
+
Source code can be downloaded as part of the \Rails project on GitHub:
|
196
196
|
|
197
197
|
* https://github.com/rails/rails/tree/main/activerecord
|
198
198
|
|
@@ -210,7 +210,7 @@ API documentation is at:
|
|
210
210
|
|
211
211
|
* https://api.rubyonrails.org
|
212
212
|
|
213
|
-
Bug reports for the Ruby on Rails project can be filed here:
|
213
|
+
Bug reports for the Ruby on \Rails project can be filed here:
|
214
214
|
|
215
215
|
* https://github.com/rails/rails/issues
|
216
216
|
|
@@ -354,11 +354,15 @@ module ActiveRecord
|
|
354
354
|
end
|
355
355
|
|
356
356
|
def normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
357
|
+
normalized_attribute =
|
358
|
+
if indexed_attribute
|
359
|
+
"#{reflection.name}[#{index}]"
|
360
|
+
else
|
361
|
+
reflection.name
|
362
|
+
end
|
363
|
+
|
364
|
+
normalized_attribute = "#{normalized_attribute}.#{attribute}" if attribute != :base
|
365
|
+
normalized_attribute
|
362
366
|
end
|
363
367
|
|
364
368
|
# Is used as an around_save callback to check while saving a collection
|
@@ -57,7 +57,7 @@ module ActiveRecord
|
|
57
57
|
fields.each_with_index do |fname, i|
|
58
58
|
ftype = result.ftype i
|
59
59
|
fmod = result.fmod i
|
60
|
-
types[fname] = get_oid_type(ftype, fmod, fname)
|
60
|
+
types[fname] = types[i] = get_oid_type(ftype, fmod, fname)
|
61
61
|
end
|
62
62
|
build_result(columns: fields, rows: result.values, column_types: types)
|
63
63
|
end
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
13
13
|
return if value.blank?
|
14
14
|
|
15
15
|
time = super
|
16
|
-
return time
|
16
|
+
return time if time.is_a?(ActiveSupport::TimeWithZone) || !time.acts_like?(:time)
|
17
17
|
|
18
18
|
# While in UTC mode, the PG gem may not return times back in "UTC" even if they were provided to Postgres in UTC.
|
19
19
|
# We prefer times always in UTC, so here we convert back.
|
@@ -480,6 +480,7 @@ module ActiveRecord
|
|
480
480
|
if column.has_default?
|
481
481
|
type = lookup_cast_type_from_column(column)
|
482
482
|
default = type.deserialize(column.default)
|
483
|
+
default = -> { column.default_function } if default.nil?
|
483
484
|
end
|
484
485
|
|
485
486
|
@definition.column(column_name, column.type,
|
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Locking
|
5
|
-
# == What is Optimistic Locking
|
5
|
+
# == What is \Optimistic \Locking
|
6
6
|
#
|
7
7
|
# Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of
|
8
8
|
# conflicts with the data. It does this by checking whether another process has made changes to a record since
|
9
|
-
# it was opened, an
|
9
|
+
# it was opened, an ActiveRecord::StaleObjectError exception is thrown if that has occurred
|
10
10
|
# and the update is ignored.
|
11
11
|
#
|
12
|
-
# Check out
|
12
|
+
# Check out +ActiveRecord::Locking::Pessimistic+ for an alternative.
|
13
13
|
#
|
14
14
|
# == Usage
|
15
15
|
#
|
@@ -69,6 +69,11 @@ module ActiveRecord
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
def initialize_dup(other) # :nodoc:
|
73
|
+
super
|
74
|
+
_clear_locking_column if locking_enabled?
|
75
|
+
end
|
76
|
+
|
72
77
|
private
|
73
78
|
def _create_record(attribute_names = self.attribute_names)
|
74
79
|
if locking_enabled?
|
@@ -91,8 +96,7 @@ module ActiveRecord
|
|
91
96
|
locking_column = self.class.locking_column
|
92
97
|
lock_attribute_was = @attributes[locking_column]
|
93
98
|
|
94
|
-
update_constraints =
|
95
|
-
update_constraints[locking_column] = _lock_value_for_database(locking_column)
|
99
|
+
update_constraints = _query_constraints_hash
|
96
100
|
|
97
101
|
attribute_names = attribute_names.dup if attribute_names.frozen?
|
98
102
|
attribute_names << locking_column
|
@@ -118,16 +122,9 @@ module ActiveRecord
|
|
118
122
|
end
|
119
123
|
|
120
124
|
def destroy_row
|
121
|
-
|
122
|
-
|
123
|
-
locking_column = self.class.locking_column
|
125
|
+
affected_rows = super
|
124
126
|
|
125
|
-
|
126
|
-
delete_constraints[locking_column] = _lock_value_for_database(locking_column)
|
127
|
-
|
128
|
-
affected_rows = self.class._delete_record(delete_constraints)
|
129
|
-
|
130
|
-
if affected_rows != 1
|
127
|
+
if locking_enabled? && affected_rows != 1
|
131
128
|
raise ActiveRecord::StaleObjectError.new(self, "destroy")
|
132
129
|
end
|
133
130
|
|
@@ -142,6 +139,18 @@ module ActiveRecord
|
|
142
139
|
end
|
143
140
|
end
|
144
141
|
|
142
|
+
def _clear_locking_column
|
143
|
+
self[self.class.locking_column] = nil
|
144
|
+
clear_attribute_change(self.class.locking_column)
|
145
|
+
end
|
146
|
+
|
147
|
+
def _query_constraints_hash
|
148
|
+
return super unless locking_enabled?
|
149
|
+
|
150
|
+
locking_column = self.class.locking_column
|
151
|
+
super.merge(locking_column => _lock_value_for_database(locking_column))
|
152
|
+
end
|
153
|
+
|
145
154
|
module ClassMethods
|
146
155
|
DEFAULT_LOCKING_COLUMN = "lock_version"
|
147
156
|
|
@@ -159,10 +168,7 @@ module ActiveRecord
|
|
159
168
|
end
|
160
169
|
|
161
170
|
# The version column used for optimistic locking. Defaults to +lock_version+.
|
162
|
-
|
163
|
-
@locking_column = DEFAULT_LOCKING_COLUMN unless defined?(@locking_column)
|
164
|
-
@locking_column
|
165
|
-
end
|
171
|
+
attr_reader :locking_column
|
166
172
|
|
167
173
|
# Reset the column used for optimistic locking back to the +lock_version+ default.
|
168
174
|
def reset_locking_column
|
@@ -182,6 +188,14 @@ module ActiveRecord
|
|
182
188
|
end
|
183
189
|
super
|
184
190
|
end
|
191
|
+
|
192
|
+
private
|
193
|
+
def inherited(base)
|
194
|
+
super
|
195
|
+
base.class_eval do
|
196
|
+
@locking_column = DEFAULT_LOCKING_COLUMN
|
197
|
+
end
|
198
|
+
end
|
185
199
|
end
|
186
200
|
end
|
187
201
|
|
@@ -813,7 +813,7 @@ module ActiveRecord
|
|
813
813
|
verify_readonly_attribute(name) || name
|
814
814
|
end
|
815
815
|
|
816
|
-
update_constraints =
|
816
|
+
update_constraints = _query_constraints_hash
|
817
817
|
attributes = attributes.each_with_object({}) do |(k, v), h|
|
818
818
|
h[k] = @attributes.write_cast_value(k, v)
|
819
819
|
clear_attribute_change(k)
|
@@ -1028,7 +1028,7 @@ module ActiveRecord
|
|
1028
1028
|
(self.class.default_scopes?(all_queries: true) || self.class.global_current_scope)
|
1029
1029
|
end
|
1030
1030
|
|
1031
|
-
def
|
1031
|
+
def _query_constraints_hash
|
1032
1032
|
{ @primary_key => id_in_database }
|
1033
1033
|
end
|
1034
1034
|
|
@@ -1041,7 +1041,7 @@ module ActiveRecord
|
|
1041
1041
|
end
|
1042
1042
|
|
1043
1043
|
def _delete_row
|
1044
|
-
self.class._delete_record(
|
1044
|
+
self.class._delete_record(_query_constraints_hash)
|
1045
1045
|
end
|
1046
1046
|
|
1047
1047
|
def _touch_row(attribute_names, time)
|
@@ -1057,7 +1057,7 @@ module ActiveRecord
|
|
1057
1057
|
def _update_row(attribute_names, attempted_action = "update")
|
1058
1058
|
self.class._update_record(
|
1059
1059
|
attributes_with_values(attribute_names),
|
1060
|
-
|
1060
|
+
_query_constraints_hash
|
1061
1061
|
)
|
1062
1062
|
end
|
1063
1063
|
|
@@ -485,6 +485,10 @@ module ActiveRecord
|
|
485
485
|
foreign_key
|
486
486
|
end
|
487
487
|
|
488
|
+
def join_primary_type
|
489
|
+
type
|
490
|
+
end
|
491
|
+
|
488
492
|
def join_foreign_key
|
489
493
|
active_record_primary_key
|
490
494
|
end
|
@@ -588,6 +592,10 @@ module ActiveRecord
|
|
588
592
|
options[:polymorphic]
|
589
593
|
end
|
590
594
|
|
595
|
+
def polymorphic_name
|
596
|
+
active_record.polymorphic_name
|
597
|
+
end
|
598
|
+
|
591
599
|
def add_as_source(seed)
|
592
600
|
seed
|
593
601
|
end
|
@@ -18,7 +18,10 @@ module ActiveRecord
|
|
18
18
|
def ids
|
19
19
|
case value
|
20
20
|
when Relation
|
21
|
-
|
21
|
+
relation = value
|
22
|
+
relation = relation.select(primary_key) if select_clause?
|
23
|
+
relation = relation.where(primary_type => polymorphic_name) if polymorphic_clause?
|
24
|
+
relation
|
22
25
|
when Array
|
23
26
|
value.map { |v| convert_to_id(v) }
|
24
27
|
else
|
@@ -30,6 +33,22 @@ module ActiveRecord
|
|
30
33
|
associated_table.join_primary_key
|
31
34
|
end
|
32
35
|
|
36
|
+
def primary_type
|
37
|
+
associated_table.join_primary_type
|
38
|
+
end
|
39
|
+
|
40
|
+
def polymorphic_name
|
41
|
+
associated_table.polymorphic_name_association
|
42
|
+
end
|
43
|
+
|
44
|
+
def select_clause?
|
45
|
+
value.select_values.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def polymorphic_clause?
|
49
|
+
primary_type && !value.where_values_hash.has_key?(primary_type)
|
50
|
+
end
|
51
|
+
|
33
52
|
def convert_to_id(value)
|
34
53
|
if value.respond_to?(primary_key)
|
35
54
|
value.public_send(primary_key)
|
@@ -77,7 +77,11 @@ module ActiveRecord
|
|
77
77
|
associations.each do |association|
|
78
78
|
reflection = scope_association_reflection(association)
|
79
79
|
@scope.joins!(association)
|
80
|
-
|
80
|
+
if @scope.table_name == reflection.table_name
|
81
|
+
self.not(association => { reflection.association_primary_key => nil })
|
82
|
+
else
|
83
|
+
self.not(reflection.table_name => { reflection.association_primary_key => nil })
|
84
|
+
end
|
81
85
|
end
|
82
86
|
|
83
87
|
@scope
|
@@ -105,7 +109,11 @@ module ActiveRecord
|
|
105
109
|
associations.each do |association|
|
106
110
|
reflection = scope_association_reflection(association)
|
107
111
|
@scope.left_outer_joins!(association)
|
108
|
-
@scope.
|
112
|
+
if @scope.table_name == reflection.table_name
|
113
|
+
@scope.where!(association => { reflection.association_primary_key => nil })
|
114
|
+
else
|
115
|
+
@scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
|
116
|
+
end
|
109
117
|
end
|
110
118
|
|
111
119
|
@scope
|
data/lib/active_record/result.rb
CHANGED
@@ -108,7 +108,7 @@ module ActiveRecord
|
|
108
108
|
type = if type_overrides.is_a?(Array)
|
109
109
|
type_overrides.first
|
110
110
|
else
|
111
|
-
column_type(columns.first, type_overrides)
|
111
|
+
column_type(columns.first, 0, type_overrides)
|
112
112
|
end
|
113
113
|
|
114
114
|
rows.map do |(value)|
|
@@ -118,7 +118,7 @@ module ActiveRecord
|
|
118
118
|
types = if type_overrides.is_a?(Array)
|
119
119
|
type_overrides
|
120
120
|
else
|
121
|
-
columns.map { |name| column_type(name, type_overrides) }
|
121
|
+
columns.map.with_index { |name, i| column_type(name, i, type_overrides) }
|
122
122
|
end
|
123
123
|
|
124
124
|
rows.map do |values|
|
@@ -135,9 +135,11 @@ module ActiveRecord
|
|
135
135
|
end
|
136
136
|
|
137
137
|
private
|
138
|
-
def column_type(name, type_overrides
|
138
|
+
def column_type(name, index, type_overrides)
|
139
139
|
type_overrides.fetch(name) do
|
140
|
-
column_types.fetch(
|
140
|
+
column_types.fetch(index) do
|
141
|
+
column_types.fetch(name, Type.default_value)
|
142
|
+
end
|
141
143
|
end
|
142
144
|
end
|
143
145
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
class TableMetadata # :nodoc:
|
5
|
-
delegate :join_primary_key, :join_foreign_key, :join_foreign_type, to: :reflection
|
5
|
+
delegate :join_primary_key, :join_primary_type, :join_foreign_key, :join_foreign_type, to: :reflection
|
6
6
|
|
7
7
|
def initialize(klass, arel_table, reflection = nil)
|
8
8
|
@klass = klass
|
@@ -54,6 +54,10 @@ module ActiveRecord
|
|
54
54
|
reflection&.polymorphic?
|
55
55
|
end
|
56
56
|
|
57
|
+
def polymorphic_name_association
|
58
|
+
reflection&.polymorphic_name
|
59
|
+
end
|
60
|
+
|
57
61
|
def through_association?
|
58
62
|
reflection&.through_reflection?
|
59
63
|
end
|
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.0.
|
4
|
+
version: 7.0.6
|
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: 2023-
|
11
|
+
date: 2023-06-29 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.0.
|
19
|
+
version: 7.0.6
|
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.0.
|
26
|
+
version: 7.0.6
|
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.0.
|
33
|
+
version: 7.0.6
|
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.0.
|
40
|
+
version: 7.0.6
|
41
41
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
42
42
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
43
43
|
migrations, and testing come baked-in.
|
@@ -434,10 +434,10 @@ licenses:
|
|
434
434
|
- MIT
|
435
435
|
metadata:
|
436
436
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
437
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.0.
|
438
|
-
documentation_uri: https://api.rubyonrails.org/v7.0.
|
437
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.6/activerecord/CHANGELOG.md
|
438
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.6/
|
439
439
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
440
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.0.
|
440
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.6/activerecord
|
441
441
|
rubygems_mfa_required: 'true'
|
442
442
|
post_install_message:
|
443
443
|
rdoc_options:
|
@@ -456,7 +456,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
456
456
|
- !ruby/object:Gem::Version
|
457
457
|
version: '0'
|
458
458
|
requirements: []
|
459
|
-
rubygems_version: 3.4.
|
459
|
+
rubygems_version: 3.4.13
|
460
460
|
signing_key:
|
461
461
|
specification_version: 4
|
462
462
|
summary: Object-relational mapper framework (part of Rails).
|