activerecord 7.0.4.3 → 7.0.6
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 +4 -4
- data/CHANGELOG.md +159 -7
- data/README.rdoc +2 -2
- data/lib/active_record/associations/has_one_association.rb +4 -0
- data/lib/active_record/associations/preloader/through_association.rb +1 -1
- data/lib/active_record/associations/singular_association.rb +7 -5
- data/lib/active_record/associations.rb +15 -6
- data/lib/active_record/attribute_methods/read.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -4
- data/lib/active_record/attribute_methods.rb +5 -7
- data/lib/active_record/autosave_association.rb +9 -5
- data/lib/active_record/callbacks.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +20 -16
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +2 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +4 -0
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -3
- data/lib/active_record/connection_adapters/mysql/quoting.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -5
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/disable_joins_association_relation.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/locking/optimistic.rb +32 -18
- data/lib/active_record/middleware/database_selector.rb +3 -3
- data/lib/active_record/migration/command_recorder.rb +1 -2
- data/lib/active_record/migration/compatibility.rb +7 -0
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/persistence.rb +4 -4
- data/lib/active_record/reflection.rb +8 -0
- data/lib/active_record/relation/calculations.rb +50 -23
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
- data/lib/active_record/relation/predicate_builder.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +11 -3
- data/lib/active_record/result.rb +6 -4
- data/lib/active_record/schema_dumper.rb +4 -0
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/table_metadata.rb +5 -1
- data/lib/active_record/type/serialized.rb +4 -4
- data/lib/arel/filter_predications.rb +1 -1
- data/lib/arel/nodes/filter.rb +1 -1
- 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: 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,155 @@
|
|
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
|
+
|
56
|
+
## Rails 7.0.5 (May 24, 2023) ##
|
57
|
+
|
58
|
+
* Type cast `#attribute_changed?` `:from` and `:to` options.
|
59
|
+
|
60
|
+
*Andrew Novoselac*
|
61
|
+
|
62
|
+
* Fix `index_exists?` when column is an array.
|
63
|
+
|
64
|
+
*Eileen M. Uchitelle*
|
65
|
+
|
66
|
+
* Handle `Date` objects for PostgreSQL `timestamptz` columns.
|
67
|
+
|
68
|
+
*Alex Ghiculescu*
|
69
|
+
|
70
|
+
* Fix collation for changing column to non-string.
|
71
|
+
|
72
|
+
*Hartley McGuire*
|
73
|
+
|
74
|
+
* Map through subtype in `PostgreSQL::OID::Array`.
|
75
|
+
|
76
|
+
*Jonathan Hefner*
|
77
|
+
|
78
|
+
* Store correct environment in `internal_metadata` when run rails `db:prepare`.
|
79
|
+
|
80
|
+
*fatkodima*
|
81
|
+
|
82
|
+
* Make sure `ActiveRecord::Relation#sum` works with objects that implement `#coerce` without deprecation.
|
83
|
+
|
84
|
+
*Alex Ghiculescu*
|
85
|
+
|
86
|
+
* Fix retrieving foreign keys referencing tables named like keywords in PostgreSQL and MySQL.
|
87
|
+
|
88
|
+
*fatkodima*
|
89
|
+
|
90
|
+
* Support UUIDs in Disable Joins.
|
91
|
+
|
92
|
+
*Samuel Cochran*
|
93
|
+
|
94
|
+
* Fix Active Record's explain for queries starting with comments.
|
95
|
+
|
96
|
+
*fatkodima*
|
97
|
+
|
98
|
+
* Fix incorrectly preloading through association records when middle association has been loaded.
|
99
|
+
|
100
|
+
*Joshua Young*
|
101
|
+
|
102
|
+
* Fix where.missing and where.associated for parent/child associations.
|
103
|
+
|
104
|
+
*fatkodima*
|
105
|
+
|
106
|
+
* Fix Enumerable#in_order_of to preserve duplicates.
|
107
|
+
|
108
|
+
*fatkodima*
|
109
|
+
|
110
|
+
* Fix autoincrement on primary key for mysql.
|
111
|
+
|
112
|
+
*Eileen M. Uchitelle*
|
113
|
+
|
114
|
+
* Restore ability to redefine column in `create_table` for Rails 5.2 migrations.
|
115
|
+
|
116
|
+
*fatkodima*
|
117
|
+
|
118
|
+
* Fix schema cache dumping of virtual columns.
|
119
|
+
|
120
|
+
*fatkodima*
|
121
|
+
|
122
|
+
* Fix Active Record grouped calculations on joined tables on column present in both tables.
|
123
|
+
|
124
|
+
*fatkodima*
|
125
|
+
|
126
|
+
* Fix mutation detection for serialized attributes backed by binary columns.
|
127
|
+
|
128
|
+
*Jean Boussier*
|
129
|
+
|
130
|
+
* Fix a bug where using groups and counts with long table names would return incorrect results.
|
131
|
+
|
132
|
+
*Shota Toguchi*, *Yusaku Ono*
|
133
|
+
|
134
|
+
* Fix erroneous nil default precision on virtual datetime columns.
|
135
|
+
|
136
|
+
Prior to this change, virtual datetime columns did not have the same
|
137
|
+
default precision as regular datetime columns, resulting in the following
|
138
|
+
being erroneously equivalent:
|
139
|
+
|
140
|
+
t.virtual :name, type: datetime, as: "expression"
|
141
|
+
t.virtual :name, type: datetime, precision: nil, as: "expression"
|
142
|
+
|
143
|
+
This change fixes the default precision lookup, so virtual and regular
|
144
|
+
datetime column default precisions match.
|
145
|
+
|
146
|
+
*Sam Bostock*
|
147
|
+
|
148
|
+
* Fix a case where the query cache can return wrong values. See #46044
|
149
|
+
|
150
|
+
*Aaron Patterson*
|
151
|
+
|
152
|
+
|
1
153
|
## Rails 7.0.4.3 (March 13, 2023) ##
|
2
154
|
|
3
155
|
* No changes.
|
@@ -17,7 +169,7 @@
|
|
17
169
|
carefully crafted input.
|
18
170
|
|
19
171
|
This commit makes the sanitization more robust by replacing any
|
20
|
-
|
172
|
+
occurrences of "/*" or "*/" with "/ *" or "* /". It also performs a
|
21
173
|
first pass to remove one surrounding comment to avoid compatibility
|
22
174
|
issues for users relying on the existing removal.
|
23
175
|
|
@@ -142,21 +294,21 @@
|
|
142
294
|
|
143
295
|
This adds two new configuration options The configuration options are as
|
144
296
|
follows:
|
145
|
-
|
146
|
-
* `config.
|
147
|
-
|
297
|
+
|
298
|
+
* `config.active_record.use_yaml_unsafe_load`
|
299
|
+
|
148
300
|
When set to true, this configuration option tells Rails to use the old
|
149
301
|
"unsafe" YAML loading strategy, maintaining the existing behavior but leaving
|
150
302
|
the possible escalation vulnerability in place. Setting this option to true
|
151
303
|
is *not* recommended, but can aid in upgrading.
|
152
|
-
|
304
|
+
|
153
305
|
* `config.active_record.yaml_column_permitted_classes`
|
154
|
-
|
306
|
+
|
155
307
|
The "safe YAML" loading method does not allow all classes to be deserialized
|
156
308
|
by default. This option allows you to specify classes deemed "safe" in your
|
157
309
|
application. For example, if your application uses Symbol and Time in
|
158
310
|
serialized data, you can add Symbol and Time to the allowed list as follows:
|
159
|
-
|
311
|
+
|
160
312
|
```
|
161
313
|
config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
|
162
314
|
```
|
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
|
|
@@ -54,11 +54,13 @@ module ActiveRecord
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def _create_record(attributes, raise_error = false, &block)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
reflection.klass.transaction do
|
58
|
+
record = build(attributes, &block)
|
59
|
+
saved = record.save
|
60
|
+
replace_keys(record, force: true)
|
61
|
+
raise RecordInvalid.new(record) if !saved && raise_error
|
62
|
+
record
|
63
|
+
end
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -586,8 +586,11 @@ module ActiveRecord
|
|
586
586
|
# has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
|
587
587
|
# end
|
588
588
|
#
|
589
|
-
# Note: Joining
|
590
|
-
#
|
589
|
+
# Note: Joining or eager loading such associations is not possible because
|
590
|
+
# those operations happen before instance creation. Such associations
|
591
|
+
# _can_ be preloaded, but doing so will perform N+1 queries because there
|
592
|
+
# will be a different scope for each record (similar to preloading
|
593
|
+
# polymorphic scopes).
|
591
594
|
#
|
592
595
|
# == Association callbacks
|
593
596
|
#
|
@@ -1600,6 +1603,12 @@ module ActiveRecord
|
|
1600
1603
|
#
|
1601
1604
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1602
1605
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1606
|
+
# [:touch]
|
1607
|
+
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1608
|
+
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1609
|
+
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1610
|
+
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1611
|
+
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1603
1612
|
# [:inverse_of]
|
1604
1613
|
# Specifies the name of the #belongs_to association on the associated object
|
1605
1614
|
# that is the inverse of this #has_one association.
|
@@ -1747,11 +1756,11 @@ module ActiveRecord
|
|
1747
1756
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
|
1748
1757
|
# sets <tt>:autosave</tt> to <tt>true</tt>.
|
1749
1758
|
# [:touch]
|
1750
|
-
# If true, the associated object will be touched (the updated_at/
|
1759
|
+
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1751
1760
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1752
|
-
# will be updated with the current time in addition to the updated_at/
|
1753
|
-
# Please note that
|
1754
|
-
# +after_commit
|
1761
|
+
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1762
|
+
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1763
|
+
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1755
1764
|
# [:inverse_of]
|
1756
1765
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1757
1766
|
# object that is the inverse of this #belongs_to association.
|
@@ -23,7 +23,7 @@ module ActiveRecord
|
|
23
23
|
|
24
24
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
25
25
|
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
26
|
-
# to a date object, like Date.new(2004, 12, 12)).
|
26
|
+
# to a date object, like <tt>Date.new(2004, 12, 12)</tt>).
|
27
27
|
def read_attribute(attr_name, &block)
|
28
28
|
name = attr_name.to_s
|
29
29
|
name = self.class.attribute_aliases[name] || name
|
@@ -19,8 +19,6 @@ module ActiveRecord
|
|
19
19
|
|
20
20
|
if value.is_a?(Hash)
|
21
21
|
set_time_zone_without_conversion(super)
|
22
|
-
elsif value.is_a?(Range)
|
23
|
-
Range.new(user_input_in_time_zone(value.begin), user_input_in_time_zone(value.end), value.exclude_end?)
|
24
22
|
elsif value.respond_to?(:in_time_zone)
|
25
23
|
begin
|
26
24
|
super(user_input_in_time_zone(value)) || super
|
@@ -42,8 +40,6 @@ module ActiveRecord
|
|
42
40
|
value.in_time_zone
|
43
41
|
elsif value.respond_to?(:infinite?) && value.infinite?
|
44
42
|
value
|
45
|
-
elsif value.is_a?(Range)
|
46
|
-
Range.new(convert_time_to_time_zone(value.begin), convert_time_to_time_zone(value.end), value.exclude_end?)
|
47
43
|
else
|
48
44
|
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
49
45
|
end
|
@@ -310,8 +310,8 @@ module ActiveRecord
|
|
310
310
|
end
|
311
311
|
|
312
312
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
313
|
-
# "2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises
|
314
|
-
#
|
313
|
+
# "2004-12-12" in a date column is cast to a date object, like <tt>Date.new(2004, 12, 12)</tt>). It raises
|
314
|
+
# ActiveModel::MissingAttributeError if the identified attribute is missing.
|
315
315
|
#
|
316
316
|
# Note: +:id+ is always present.
|
317
317
|
#
|
@@ -331,7 +331,6 @@ module ActiveRecord
|
|
331
331
|
end
|
332
332
|
|
333
333
|
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
|
334
|
-
# (Alias for the protected #write_attribute method).
|
335
334
|
#
|
336
335
|
# class Person < ActiveRecord::Base
|
337
336
|
# end
|
@@ -360,10 +359,9 @@ module ActiveRecord
|
|
360
359
|
# end
|
361
360
|
#
|
362
361
|
# private
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
366
|
-
# end
|
362
|
+
# def print_accessed_fields
|
363
|
+
# p @posts.first.accessed_fields
|
364
|
+
# end
|
367
365
|
# end
|
368
366
|
#
|
369
367
|
# Which allows you to quickly change your code to:
|
@@ -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
|
@@ -224,14 +224,13 @@ module ActiveRecord
|
|
224
224
|
# after_save :do_something_else
|
225
225
|
#
|
226
226
|
# private
|
227
|
+
# def log_children
|
228
|
+
# # Child processing
|
229
|
+
# end
|
227
230
|
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# def do_something_else
|
233
|
-
# # Something else
|
234
|
-
# end
|
231
|
+
# def do_something_else
|
232
|
+
# # Something else
|
233
|
+
# end
|
235
234
|
# end
|
236
235
|
#
|
237
236
|
# In this case the +log_children+ is executed before +do_something_else+.
|
@@ -249,14 +248,13 @@ module ActiveRecord
|
|
249
248
|
# after_commit :do_something_else
|
250
249
|
#
|
251
250
|
# private
|
251
|
+
# def log_children
|
252
|
+
# # Child processing
|
253
|
+
# end
|
252
254
|
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
# def do_something_else
|
258
|
-
# # Something else
|
259
|
-
# end
|
255
|
+
# def do_something_else
|
256
|
+
# # Something else
|
257
|
+
# end
|
260
258
|
# end
|
261
259
|
#
|
262
260
|
# In this case the +do_something_else+ is executed before +log_children+.
|
@@ -411,20 +411,7 @@ module ActiveRecord
|
|
411
411
|
name = name.to_s
|
412
412
|
type = type.to_sym if type
|
413
413
|
|
414
|
-
|
415
|
-
if @columns_hash[name].primary_key?
|
416
|
-
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
417
|
-
else
|
418
|
-
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
if @conn.supports_datetime_with_precision?
|
423
|
-
if type == :datetime && !options.key?(:precision)
|
424
|
-
options[:precision] = 6
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
414
|
+
raise_on_duplicate_column(name)
|
428
415
|
@columns_hash[name] = new_column_definition(name, type, **options)
|
429
416
|
|
430
417
|
if index
|
@@ -491,6 +478,13 @@ module ActiveRecord
|
|
491
478
|
type = integer_like_primary_key_type(type, options)
|
492
479
|
end
|
493
480
|
type = aliased_types(type.to_s, type)
|
481
|
+
|
482
|
+
if @conn.supports_datetime_with_precision?
|
483
|
+
if type == :datetime && !options.key?(:precision)
|
484
|
+
options[:precision] = 6
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
494
488
|
options[:primary_key] ||= type == :primary_key
|
495
489
|
options[:null] = false if options[:primary_key]
|
496
490
|
create_column_definition(name, type, options)
|
@@ -525,6 +519,16 @@ module ActiveRecord
|
|
525
519
|
def integer_like_primary_key_type(type, options)
|
526
520
|
type
|
527
521
|
end
|
522
|
+
|
523
|
+
def raise_on_duplicate_column(name)
|
524
|
+
if @columns_hash[name]
|
525
|
+
if @columns_hash[name].primary_key?
|
526
|
+
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
527
|
+
else
|
528
|
+
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
529
|
+
end
|
530
|
+
end
|
531
|
+
end
|
528
532
|
end
|
529
533
|
|
530
534
|
class AlterTable # :nodoc:
|
@@ -661,8 +665,8 @@ module ActiveRecord
|
|
661
665
|
# end
|
662
666
|
#
|
663
667
|
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
|
664
|
-
def index_exists?(column_name, options
|
665
|
-
@base.index_exists?(name, column_name, options)
|
668
|
+
def index_exists?(column_name, **options)
|
669
|
+
@base.index_exists?(name, column_name, **options)
|
666
670
|
end
|
667
671
|
|
668
672
|
# Renames the given index on the table.
|
@@ -98,6 +98,7 @@ module ActiveRecord
|
|
98
98
|
#
|
99
99
|
def index_exists?(table_name, column_name, **options)
|
100
100
|
checks = []
|
101
|
+
column_name = options[:column] if column_name.nil?
|
101
102
|
|
102
103
|
if column_name.present?
|
103
104
|
column_names = Array(column_name).map(&:to_s)
|
@@ -263,7 +264,7 @@ module ActiveRecord
|
|
263
264
|
#
|
264
265
|
# generates:
|
265
266
|
#
|
266
|
-
# CREATE TABLE
|
267
|
+
# CREATE TABLE orders (
|
267
268
|
# product_id bigint NOT NULL,
|
268
269
|
# client_id bigint NOT NULL
|
269
270
|
# );
|
@@ -593,6 +593,10 @@ module ActiveRecord
|
|
593
593
|
#
|
594
594
|
# This is useful for when you need to call a proprietary method such as
|
595
595
|
# PostgreSQL's lo_* methods.
|
596
|
+
#
|
597
|
+
# Active Record cannot track if the database is getting modified using
|
598
|
+
# this client. If that is the case, generally you'll want to invalidate
|
599
|
+
# the query cache using +ActiveRecord::Base.clear_query_cache+.
|
596
600
|
def raw_connection
|
597
601
|
disable_lazy_transactions!
|
598
602
|
@connection
|
@@ -403,7 +403,7 @@ module ActiveRecord
|
|
403
403
|
|
404
404
|
fk_info.map do |row|
|
405
405
|
options = {
|
406
|
-
column: row["column"],
|
406
|
+
column: unquote_identifier(row["column"]),
|
407
407
|
name: row["name"],
|
408
408
|
primary_key: row["primary_key"]
|
409
409
|
}
|
@@ -411,7 +411,7 @@ module ActiveRecord
|
|
411
411
|
options[:on_update] = extract_foreign_key_action(row["on_update"])
|
412
412
|
options[:on_delete] = extract_foreign_key_action(row["on_delete"])
|
413
413
|
|
414
|
-
ForeignKeyDefinition.new(table_name, row["to_table"], options)
|
414
|
+
ForeignKeyDefinition.new(table_name, unquote_identifier(row["to_table"]), options)
|
415
415
|
end
|
416
416
|
end
|
417
417
|
|
@@ -619,6 +619,10 @@ module ActiveRecord
|
|
619
619
|
end
|
620
620
|
|
621
621
|
private
|
622
|
+
def text_type?(type)
|
623
|
+
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
|
624
|
+
end
|
625
|
+
|
622
626
|
def type_map
|
623
627
|
emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP
|
624
628
|
end
|
@@ -712,7 +716,7 @@ module ActiveRecord
|
|
712
716
|
end
|
713
717
|
|
714
718
|
unless options.key?(:collation)
|
715
|
-
options[:collation] = column.collation
|
719
|
+
options[:collation] = column.collation if text_type?(type)
|
716
720
|
end
|
717
721
|
|
718
722
|
unless options.key?(:auto_increment)
|
@@ -51,6 +51,14 @@ module ActiveRecord
|
|
51
51
|
"x'#{value.hex}'"
|
52
52
|
end
|
53
53
|
|
54
|
+
def unquote_identifier(identifier)
|
55
|
+
if identifier && identifier.start_with?("`")
|
56
|
+
identifier[1..-2]
|
57
|
+
else
|
58
|
+
identifier
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
54
62
|
# Override +type_cast+ we pass to mysql2 Date and Time objects instead
|
55
63
|
# of Strings since mysql2 is able to handle those classes more efficiently.
|
56
64
|
def type_cast(value) # :nodoc:
|
@@ -57,11 +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
|
-
|
61
|
-
when Type::Integer, Type::Float, OID::Decimal, Type::String, Type::DateTime, Type::Boolean
|
62
|
-
# skip if a column has already been type casted by pg decoders
|
63
|
-
else types[fname] = type
|
64
|
-
end
|
60
|
+
types[fname] = types[i] = get_oid_type(ftype, fmod, fname)
|
65
61
|
end
|
66
62
|
build_result(columns: fields, rows: result.values, column_types: types)
|
67
63
|
end
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
13
13
|
return if value.blank?
|
14
14
|
|
15
15
|
time = super
|
16
|
-
return time if time.is_a?(ActiveSupport::TimeWithZone)
|
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.
|
@@ -498,7 +498,7 @@ module ActiveRecord
|
|
498
498
|
|
499
499
|
fk_info.map do |row|
|
500
500
|
options = {
|
501
|
-
column: row["column"],
|
501
|
+
column: Utils.unquote_identifier(row["column"]),
|
502
502
|
name: row["name"],
|
503
503
|
primary_key: row["primary_key"]
|
504
504
|
}
|
@@ -508,8 +508,9 @@ module ActiveRecord
|
|
508
508
|
options[:deferrable] = extract_foreign_key_deferrable(row["deferrable"], row["deferred"])
|
509
509
|
|
510
510
|
options[:validate] = row["valid"]
|
511
|
+
to_table = Utils.unquote_identifier(row["to_table"])
|
511
512
|
|
512
|
-
ForeignKeyDefinition.new(table_name,
|
513
|
+
ForeignKeyDefinition.new(table_name, to_table, options)
|
513
514
|
end
|
514
515
|
end
|
515
516
|
|