activerecord 6.0.6 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +783 -910
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +22 -14
- data/lib/active_record/associations/alias_tracker.rb +19 -15
- data/lib/active_record/associations/association.rb +43 -26
- data/lib/active_record/associations/association_scope.rb +11 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +19 -13
- data/lib/active_record/associations/collection_proxy.rb +12 -5
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -2
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +63 -49
- data/lib/active_record/associations/preloader/association.rb +13 -5
- data/lib/active_record/associations/preloader/through_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +5 -3
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations.rb +114 -11
- data/lib/active_record/attribute_assignment.rb +10 -8
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
- data/lib/active_record/attribute_methods/dirty.rb +1 -11
- data/lib/active_record/attribute_methods/primary_key.rb +6 -2
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -11
- data/lib/active_record/attribute_methods/serialization.rb +11 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
- data/lib/active_record/attribute_methods/write.rb +12 -20
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attributes.rb +32 -7
- data/lib/active_record/autosave_association.rb +47 -30
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +152 -22
- data/lib/active_record/coders/yaml_column.rb +2 -24
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
- data/lib/active_record/connection_adapters/abstract/transaction.rb +80 -32
- data/lib/active_record/connection_adapters/abstract_adapter.rb +49 -72
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -24
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_handling.rb +210 -71
- data/lib/active_record/core.rb +223 -66
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -40
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/enum.rb +27 -10
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -4
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -2
- data/lib/active_record/fixtures.rb +54 -8
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +40 -18
- data/lib/active_record/insert_all.rb +34 -5
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +13 -16
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +26 -8
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
- data/lib/active_record/middleware/database_selector.rb +4 -1
- data/lib/active_record/migration/command_recorder.rb +47 -27
- data/lib/active_record/migration/compatibility.rb +67 -17
- data/lib/active_record/migration.rb +113 -83
- data/lib/active_record/model_schema.rb +88 -13
- data/lib/active_record/nested_attributes.rb +2 -3
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +50 -45
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +11 -6
- data/lib/active_record/railtie.rb +64 -44
- data/lib/active_record/railties/databases.rake +266 -95
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +60 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +38 -31
- data/lib/active_record/relation/calculations.rb +100 -43
- data/lib/active_record/relation/finder_methods.rb +44 -14
- data/lib/active_record/relation/from_clause.rb +1 -1
- data/lib/active_record/relation/merger.rb +20 -23
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +57 -33
- data/lib/active_record/relation/query_methods.rb +318 -195
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +104 -57
- data/lib/active_record/relation.rb +90 -64
- data/lib/active_record/result.rb +41 -33
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping/named.rb +1 -17
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +2 -2
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -51
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +36 -33
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/touch_later.rb +21 -21
- data/lib/active_record/transactions.rb +15 -64
- data/lib/active_record/type/serialized.rb +6 -2
- data/lib/active_record/type.rb +8 -1
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record.rb +7 -14
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/predications.rb +12 -18
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors/dot.rb +14 -2
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -4
- data/lib/arel/visitors/to_sql.rb +89 -78
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +5 -13
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
- data/lib/rails/generators/active_record/migration.rb +6 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +28 -30
- data/lib/active_record/advisory_lock_base.rb +0 -18
- data/lib/active_record/attribute_decorators.rb +0 -88
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -203
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -156
- data/lib/arel/visitors/oracle.rb +0 -158
- data/lib/arel/visitors/oracle12.rb +0 -65
- data/lib/arel/visitors/where_sql.rb +0 -22
data/CHANGELOG.md
CHANGED
@@ -1,84 +1,4 @@
|
|
1
|
-
## Rails 6.0
|
2
|
-
|
3
|
-
* Symbol is allowed by default for YAML columns
|
4
|
-
|
5
|
-
*Étienne Barrié*
|
6
|
-
|
7
|
-
|
8
|
-
## Rails 6.0.5.1 (July 12, 2022) ##
|
9
|
-
|
10
|
-
* Change ActiveRecord::Coders::YAMLColumn default to safe_load
|
11
|
-
|
12
|
-
This adds two new configuration options The configuration options are as
|
13
|
-
follows:
|
14
|
-
|
15
|
-
* `config.active_storage.use_yaml_unsafe_load`
|
16
|
-
|
17
|
-
When set to true, this configuration option tells Rails to use the old
|
18
|
-
"unsafe" YAML loading strategy, maintaining the existing behavior but leaving
|
19
|
-
the possible escalation vulnerability in place. Setting this option to true
|
20
|
-
is *not* recommended, but can aid in upgrading.
|
21
|
-
|
22
|
-
* `config.active_record.yaml_column_permitted_classes`
|
23
|
-
|
24
|
-
The "safe YAML" loading method does not allow all classes to be deserialized
|
25
|
-
by default. This option allows you to specify classes deemed "safe" in your
|
26
|
-
application. For example, if your application uses Symbol and Time in
|
27
|
-
serialized data, you can add Symbol and Time to the allowed list as follows:
|
28
|
-
|
29
|
-
```
|
30
|
-
config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
|
31
|
-
```
|
32
|
-
|
33
|
-
[CVE-2022-32224]
|
34
|
-
|
35
|
-
|
36
|
-
## Rails 6.0.5 (May 09, 2022) ##
|
37
|
-
|
38
|
-
* No changes.
|
39
|
-
|
40
|
-
|
41
|
-
## Rails 6.0.4.8 (April 26, 2022) ##
|
42
|
-
|
43
|
-
* No changes.
|
44
|
-
|
45
|
-
|
46
|
-
## Rails 6.0.4.7 (March 08, 2022) ##
|
47
|
-
|
48
|
-
* No changes.
|
49
|
-
|
50
|
-
|
51
|
-
## Rails 6.0.4.6 (February 11, 2022) ##
|
52
|
-
|
53
|
-
* No changes.
|
54
|
-
|
55
|
-
|
56
|
-
## Rails 6.0.4.5 (February 11, 2022) ##
|
57
|
-
|
58
|
-
* No changes.
|
59
|
-
|
60
|
-
|
61
|
-
## Rails 6.0.4.4 (December 15, 2021) ##
|
62
|
-
|
63
|
-
* No changes.
|
64
|
-
|
65
|
-
|
66
|
-
## Rails 6.0.4.3 (December 14, 2021) ##
|
67
|
-
|
68
|
-
* No changes.
|
69
|
-
|
70
|
-
|
71
|
-
## Rails 6.0.4.2 (December 14, 2021) ##
|
72
|
-
|
73
|
-
* No changes.
|
74
|
-
|
75
|
-
|
76
|
-
## Rails 6.0.4.1 (August 19, 2021) ##
|
77
|
-
|
78
|
-
* No changes.
|
79
|
-
|
80
|
-
|
81
|
-
## Rails 6.0.4 (June 15, 2021) ##
|
1
|
+
## Rails 6.1.0 (December 09, 2020) ##
|
82
2
|
|
83
3
|
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
84
4
|
|
@@ -86,1345 +6,1298 @@
|
|
86
6
|
|
87
7
|
*Alex Ghiculescu*
|
88
8
|
|
89
|
-
*
|
90
|
-
|
91
|
-
Fixes #34255.
|
92
|
-
|
93
|
-
*Steven Weber*
|
94
|
-
|
95
|
-
* Reset statement cache for association if `table_name` is changed.
|
96
|
-
|
97
|
-
Fixes #36453.
|
98
|
-
|
99
|
-
*Ryuta Kamizono*
|
100
|
-
|
101
|
-
* Type cast extra select for eager loading.
|
102
|
-
|
103
|
-
*Ryuta Kamizono*
|
104
|
-
|
105
|
-
* Prevent collection associations from being autosaved multiple times.
|
9
|
+
* Change `attribute_for_inspect` to take `filter_attributes` in consideration.
|
106
10
|
|
107
|
-
|
11
|
+
*Rafael Mendonça França*
|
108
12
|
|
109
|
-
|
13
|
+
* Fix odd behavior of inverse_of with multiple belongs_to to same class.
|
110
14
|
|
111
|
-
|
15
|
+
Fixes #35204.
|
112
16
|
|
113
|
-
|
114
|
-
`ActiveRecord::Persistence.upsert_all` was used with the name of an expression index, an error
|
115
|
-
was raised. Adding a guard around the formatting behavior for the `:unique_by` corrects this.
|
17
|
+
*Tomoyuki Kai*
|
116
18
|
|
117
|
-
|
19
|
+
* Build predicate conditions with objects that delegate `#id` and primary key:
|
118
20
|
|
119
21
|
```ruby
|
120
|
-
|
121
|
-
|
122
|
-
|
22
|
+
class AdminAuthor
|
23
|
+
delegate_missing_to :@author
|
24
|
+
|
25
|
+
def initialize(author)
|
26
|
+
@author = author
|
27
|
+
end
|
123
28
|
end
|
124
29
|
|
125
|
-
|
30
|
+
Post.where(author: AdminAuthor.new(author))
|
126
31
|
```
|
127
32
|
|
128
|
-
|
129
|
-
|
130
|
-
*Austen Madden*
|
131
|
-
|
132
|
-
* Fix preloading for polymorphic association with custom scope.
|
133
|
-
|
134
|
-
*Ryuta Kamizono*
|
135
|
-
|
136
|
-
* Allow relations with different SQL comments in the `or` method.
|
33
|
+
*Sean Doyle*
|
137
34
|
|
138
|
-
|
35
|
+
* Add `connected_to_many` API.
|
139
36
|
|
140
|
-
|
37
|
+
This API allows applications to connect to multiple databases at once without switching all of them or implementing a deeply nested stack.
|
141
38
|
|
142
|
-
|
143
|
-
cache. This avoids raising an unnecessary `ActiveRecord::StaleObjectError`
|
144
|
-
upon subsequent transactions by maintaining parity with the corresponding
|
145
|
-
database record's `lock_version` column.
|
39
|
+
Before:
|
146
40
|
|
147
|
-
|
41
|
+
AnimalsRecord.connected_to(role: :reading) do
|
42
|
+
MealsRecord.connected_to(role: :reading) do
|
43
|
+
Dog.first # read from animals replica
|
44
|
+
Dinner.first # read from meals replica
|
45
|
+
Person.first # read from primary writer
|
46
|
+
end
|
47
|
+
end
|
148
48
|
|
149
|
-
|
49
|
+
After:
|
150
50
|
|
151
|
-
|
51
|
+
ActiveRecord::Base.connected_to_many([AnimalsRecord, MealsRecord], role: :reading) do
|
52
|
+
Dog.first # read from animals replica
|
53
|
+
Dinner.first # read from meals replica
|
54
|
+
Person.first # read from primary writer
|
55
|
+
end
|
152
56
|
|
153
|
-
*
|
57
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
154
58
|
|
155
|
-
*
|
59
|
+
* Add option to raise or log for `ActiveRecord::StrictLoadingViolationError`.
|
156
60
|
|
157
|
-
|
61
|
+
Some applications may not want to raise an error in production if using `strict_loading`. This would allow an application to set strict loading to log for the production environment while still raising in development and test environments.
|
158
62
|
|
159
|
-
|
63
|
+
Set `config.active_record.action_on_strict_loading_violation` to `:log` errors instead of raising.
|
160
64
|
|
161
|
-
*
|
65
|
+
*Eileen M. Uchitelle*
|
162
66
|
|
163
|
-
*
|
67
|
+
* Allow the inverse of a `has_one` association that was previously autosaved to be loaded.
|
164
68
|
|
165
|
-
|
69
|
+
Fixes #34255.
|
166
70
|
|
167
|
-
*
|
71
|
+
*Steven Weber*
|
168
72
|
|
169
|
-
|
73
|
+
* Optimise the length of index names for polymorphic references by using the reference name rather than the type and id column names.
|
170
74
|
|
171
|
-
|
75
|
+
Because the default behaviour when adding an index with multiple columns is to use all column names in the index name, this could frequently lead to overly long index names for polymorphic references which would fail the migration if it exceeded the database limit.
|
172
76
|
|
173
|
-
|
77
|
+
This change reduces the chance of that happening by using the reference name, e.g. `index_my_table_on_my_reference`.
|
174
78
|
|
175
|
-
|
176
|
-
doesn't support the feature.
|
79
|
+
Fixes #38655.
|
177
80
|
|
178
|
-
*
|
81
|
+
*Luke Redpath*
|
179
82
|
|
180
|
-
*
|
83
|
+
* MySQL: Uniqueness validator now respects default database collation,
|
84
|
+
no longer enforce case sensitive comparison by default.
|
181
85
|
|
182
86
|
*Ryuta Kamizono*
|
183
87
|
|
184
|
-
*
|
185
|
-
|
186
|
-
*Bogdan Gusiev*
|
187
|
-
|
188
|
-
|
189
|
-
## Rails 6.0.3.7 (May 05, 2021) ##
|
190
|
-
|
191
|
-
* No changes.
|
192
|
-
|
193
|
-
|
194
|
-
## Rails 6.0.3.6 (March 26, 2021) ##
|
195
|
-
|
196
|
-
* No changes.
|
197
|
-
|
198
|
-
|
199
|
-
## Rails 6.0.3.5 (February 10, 2021) ##
|
200
|
-
|
201
|
-
* Fix possible DoS vector in PostgreSQL money type
|
88
|
+
* Remove deprecated methods from `ActiveRecord::ConnectionAdapters::DatabaseLimits`.
|
202
89
|
|
203
|
-
|
204
|
-
|
205
|
-
|
90
|
+
`column_name_length`
|
91
|
+
`table_name_length`
|
92
|
+
`columns_per_table`
|
93
|
+
`indexes_per_table`
|
94
|
+
`columns_per_multicolumn_index`
|
95
|
+
`sql_query_length`
|
96
|
+
`joins_per_query`
|
206
97
|
|
207
|
-
|
208
|
-
|
209
|
-
[CVE-2021-22880]
|
98
|
+
*Rafael Mendonça França*
|
210
99
|
|
211
|
-
|
100
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_multi_insert?`.
|
212
101
|
|
102
|
+
*Rafael Mendonça França*
|
213
103
|
|
214
|
-
|
104
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_foreign_keys_in_create?`.
|
215
105
|
|
216
|
-
*
|
106
|
+
*Rafael Mendonça França*
|
217
107
|
|
108
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#supports_ranges?`.
|
218
109
|
|
219
|
-
|
110
|
+
*Rafael Mendonça França*
|
220
111
|
|
221
|
-
*
|
112
|
+
* Remove deprecated `ActiveRecord::Base#update_attributes` and `ActiveRecord::Base#update_attributes!`.
|
222
113
|
|
114
|
+
*Rafael Mendonça França*
|
223
115
|
|
224
|
-
|
116
|
+
* Remove deprecated `migrations_path` argument in `ActiveRecord::ConnectionAdapter::SchemaStatements#assume_migrated_upto_version`.
|
225
117
|
|
226
|
-
*
|
118
|
+
*Rafael Mendonça França*
|
227
119
|
|
120
|
+
* Remove deprecated `config.active_record.sqlite3.represent_boolean_as_integer`.
|
228
121
|
|
229
|
-
|
122
|
+
*Rafael Mendonça França*
|
230
123
|
|
231
|
-
*
|
124
|
+
* `relation.create` does no longer leak scope to class level querying methods
|
125
|
+
in initialization block and callbacks.
|
232
126
|
|
127
|
+
Before:
|
233
128
|
|
234
|
-
|
129
|
+
User.where(name: "John").create do |john|
|
130
|
+
User.find_by(name: "David") # => nil
|
131
|
+
end
|
235
132
|
|
236
|
-
|
133
|
+
After:
|
237
134
|
|
238
|
-
|
135
|
+
User.where(name: "John").create do |john|
|
136
|
+
User.find_by(name: "David") # => #<User name: "David", ...>
|
137
|
+
end
|
239
138
|
|
240
|
-
*
|
139
|
+
*Ryuta Kamizono*
|
241
140
|
|
242
|
-
*
|
141
|
+
* Named scope chain does no longer leak scope to class level querying methods.
|
243
142
|
|
244
|
-
|
143
|
+
class User < ActiveRecord::Base
|
144
|
+
scope :david, -> { User.where(name: "David") }
|
145
|
+
end
|
245
146
|
|
246
|
-
|
147
|
+
Before:
|
247
148
|
|
248
|
-
|
149
|
+
User.where(name: "John").david
|
150
|
+
# SELECT * FROM users WHERE name = 'John' AND name = 'David'
|
249
151
|
|
250
|
-
|
152
|
+
After:
|
251
153
|
|
252
|
-
|
154
|
+
User.where(name: "John").david
|
155
|
+
# SELECT * FROM users WHERE name = 'David'
|
253
156
|
|
254
|
-
*
|
157
|
+
*Ryuta Kamizono*
|
255
158
|
|
256
|
-
*
|
159
|
+
* Remove deprecated methods from `ActiveRecord::DatabaseConfigurations`.
|
257
160
|
|
258
|
-
|
161
|
+
`fetch`
|
162
|
+
`each`
|
163
|
+
`first`
|
164
|
+
`values`
|
165
|
+
`[]=`
|
259
166
|
|
260
|
-
*
|
167
|
+
*Rafael Mendonça França*
|
261
168
|
|
262
|
-
*
|
169
|
+
* `where.not` now generates NAND predicates instead of NOR.
|
263
170
|
|
264
|
-
|
171
|
+
Before:
|
265
172
|
|
266
|
-
|
173
|
+
User.where.not(name: "Jon", role: "admin")
|
174
|
+
# SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
|
267
175
|
|
268
|
-
|
176
|
+
After:
|
269
177
|
|
270
|
-
|
178
|
+
User.where.not(name: "Jon", role: "admin")
|
179
|
+
# SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
|
271
180
|
|
272
|
-
|
181
|
+
*Rafael Mendonça França*
|
273
182
|
|
274
|
-
|
183
|
+
* Remove deprecated `ActiveRecord::Result#to_hash` method.
|
275
184
|
|
276
|
-
*
|
277
|
-
ActiveRecord::Relation#cache_key_with_version. This method will be used by
|
278
|
-
ActionController::ConditionalGet to ensure that when collection cache versioning
|
279
|
-
is enabled, requests using ConditionalGet don't return the same ETag header
|
280
|
-
after a collection is modified. Fixes #38078.
|
185
|
+
*Rafael Mendonça França*
|
281
186
|
|
282
|
-
|
187
|
+
* Deprecate `ActiveRecord::Base.allow_unsafe_raw_sql`.
|
283
188
|
|
284
|
-
*
|
189
|
+
*Rafael Mendonça França*
|
285
190
|
|
286
|
-
|
191
|
+
* Remove deprecated support for using unsafe raw SQL in `ActiveRecord::Relation` methods.
|
287
192
|
|
288
|
-
*
|
193
|
+
*Rafael Mendonça França*
|
289
194
|
|
290
|
-
|
195
|
+
* Allow users to silence the "Rails couldn't infer whether you are using multiple databases..."
|
196
|
+
message using `config.active_record.suppress_multiple_database_warning`.
|
291
197
|
|
292
|
-
*
|
198
|
+
*Omri Gabay*
|
293
199
|
|
200
|
+
* Connections can be granularly switched for abstract classes when `connected_to` is called.
|
294
201
|
|
295
|
-
|
202
|
+
This change allows `connected_to` to switch a `role` and/or `shard` for a single abstract class instead of all classes globally. Applications that want to use the new feature need to set `config.active_record.legacy_connection_handling` to `false` in their application configuration.
|
296
203
|
|
297
|
-
|
204
|
+
Example usage:
|
298
205
|
|
206
|
+
Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`.
|
299
207
|
|
300
|
-
|
208
|
+
```ruby
|
209
|
+
ActiveRecord::Base.connected_to(role: :reading) do
|
210
|
+
User.first # reads from default replica
|
211
|
+
Dog.first # reads from default replica
|
301
212
|
|
302
|
-
|
213
|
+
AnimalsRecord.connected_to(role: :writing, shard: :one) do
|
214
|
+
User.first # reads from default replica
|
215
|
+
Dog.first # reads from shard one primary
|
216
|
+
end
|
303
217
|
|
218
|
+
User.first # reads from default replica
|
219
|
+
Dog.first # reads from default replica
|
304
220
|
|
305
|
-
|
221
|
+
ApplicationRecord.connected_to(role: :writing, shard: :two) do
|
222
|
+
User.first # reads from shard two primary
|
223
|
+
Dog.first # reads from default replica
|
224
|
+
end
|
225
|
+
end
|
226
|
+
```
|
306
227
|
|
307
|
-
*
|
308
|
-
transactional tests for the same database.
|
228
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
309
229
|
|
310
|
-
|
230
|
+
* Allow double-dash comment syntax when querying read-only databases
|
311
231
|
|
312
|
-
*
|
313
|
-
but not the entire collection.
|
232
|
+
*James Adam*
|
314
233
|
|
315
|
-
|
234
|
+
* Add `values_at` method.
|
316
235
|
|
317
|
-
|
236
|
+
Returns an array containing the values associated with the given methods.
|
318
237
|
|
319
|
-
|
238
|
+
```ruby
|
239
|
+
topic = Topic.first
|
240
|
+
topic.values_at(:title, :author_name)
|
241
|
+
# => ["Budget", "Jason"]
|
242
|
+
```
|
320
243
|
|
321
|
-
|
244
|
+
Similar to `Hash#values_at` but on an Active Record instance.
|
322
245
|
|
323
|
-
|
324
|
-
doing a relation query like `where.not(relation: { ... })`
|
325
|
-
wouldn't be properly deprecated and `where.not` would work as
|
326
|
-
NAND instead.
|
246
|
+
*Guillaume Briday*
|
327
247
|
|
328
|
-
|
248
|
+
* Fix `read_attribute_before_type_cast` to consider attribute aliases.
|
329
249
|
|
330
|
-
*
|
331
|
-
to the previous database.
|
250
|
+
*Marcelo Lauxen*
|
332
251
|
|
333
|
-
|
334
|
-
resulting in the last one to be used by subsequent rake tasks.
|
335
|
-
We should reestablish a connection to the connection that was
|
336
|
-
established before the migrate tasks was run
|
252
|
+
* Support passing record to uniqueness validator `:conditions` callable:
|
337
253
|
|
338
|
-
|
254
|
+
```ruby
|
255
|
+
class Article < ApplicationRecord
|
256
|
+
validates_uniqueness_of :title, conditions: ->(article) {
|
257
|
+
published_at = article.published_at
|
258
|
+
where(published_at: published_at.beginning_of_year..published_at.end_of_year)
|
259
|
+
}
|
260
|
+
end
|
261
|
+
```
|
339
262
|
|
340
|
-
*
|
263
|
+
*Eliot Sykes*
|
341
264
|
|
342
|
-
|
265
|
+
* `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
|
266
|
+
total number of rows affected, just like their non-batched counterparts.
|
343
267
|
|
268
|
+
```ruby
|
269
|
+
Person.in_batches.update_all("first_name = 'Eugene'") # => 42
|
270
|
+
Person.in_batches.delete_all # => 42
|
271
|
+
```
|
344
272
|
|
345
|
-
|
346
|
-
|
347
|
-
* Common Table Expressions are allowed on read-only connections.
|
273
|
+
Fixes #40287.
|
348
274
|
|
349
|
-
|
275
|
+
*Eugene Kenny*
|
350
276
|
|
351
|
-
*
|
277
|
+
* Add support for PostgreSQL `interval` data type with conversion to
|
278
|
+
`ActiveSupport::Duration` when loading records from database and
|
279
|
+
serialization to ISO 8601 formatted duration string on save.
|
280
|
+
Add support to define a column in migrations and get it in a schema dump.
|
281
|
+
Optional column precision is supported.
|
352
282
|
|
353
|
-
|
283
|
+
To use this in 6.1, you need to place the next string to your model file:
|
354
284
|
|
355
|
-
|
285
|
+
attribute :duration, :interval
|
356
286
|
|
357
|
-
|
287
|
+
To keep old behavior until 6.2 is released:
|
358
288
|
|
359
|
-
|
360
|
-
context is used.
|
289
|
+
attribute :duration, :string
|
361
290
|
|
362
|
-
|
291
|
+
Example:
|
363
292
|
|
364
|
-
|
365
|
-
|
293
|
+
create_table :events do |t|
|
294
|
+
t.string :name
|
295
|
+
t.interval :duration
|
296
|
+
end
|
366
297
|
|
367
|
-
|
298
|
+
class Event < ApplicationRecord
|
299
|
+
attribute :duration, :interval
|
300
|
+
end
|
368
301
|
|
369
|
-
|
370
|
-
|
302
|
+
Event.create!(name: 'Rock Fest', duration: 2.days)
|
303
|
+
Event.last.duration # => 2 days
|
304
|
+
Event.last.duration.iso8601 # => "P2D"
|
305
|
+
Event.new(duration: 'P1DT12H3S').duration # => 1 day, 12 hours, and 3 seconds
|
306
|
+
Event.new(duration: '1 day') # Unknown value will be ignored and NULL will be written to database
|
371
307
|
|
372
|
-
|
308
|
+
*Andrey Novikov*
|
373
309
|
|
374
|
-
*
|
310
|
+
* Allow associations supporting the `dependent:` key to take `dependent: :destroy_async`.
|
375
311
|
|
376
|
-
|
312
|
+
```ruby
|
313
|
+
class Account < ActiveRecord::Base
|
314
|
+
belongs_to :supplier, dependent: :destroy_async
|
315
|
+
end
|
316
|
+
```
|
377
317
|
|
378
|
-
|
318
|
+
`:destroy_async` will enqueue a job to destroy associated records in the background.
|
379
319
|
|
380
|
-
*
|
320
|
+
*DHH*, *George Claghorn*, *Cory Gwin*, *Rafael Mendonça França*, *Adrianna Chang*
|
381
321
|
|
382
|
-
*
|
322
|
+
* Add `SKIP_TEST_DATABASE` environment variable to disable modifying the test database when `rails db:create` and `rails db:drop` are called.
|
383
323
|
|
384
|
-
*
|
324
|
+
*Jason Schweier*
|
385
325
|
|
386
|
-
*
|
387
|
-
fixes that idle connections in forked processes wouldn't be reaped.
|
326
|
+
* `connects_to` can only be called on `ActiveRecord::Base` or abstract classes.
|
388
327
|
|
389
|
-
|
328
|
+
Ensure that `connects_to` can only be called from `ActiveRecord::Base` or abstract classes. This protects the application from opening duplicate or too many connections.
|
390
329
|
|
391
|
-
*
|
392
|
-
when `ActiveRecord::Relation#reset` or `ActiveRecord::Relation#reload`
|
393
|
-
is called.
|
330
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
394
331
|
|
395
|
-
|
332
|
+
* All connection adapters `execute` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
333
|
+
`ActiveRecord::StatementInvalid` when they encounter a connection error.
|
396
334
|
|
397
|
-
*
|
335
|
+
*Jean Boussier*
|
398
336
|
|
399
|
-
|
337
|
+
* `Mysql2Adapter#quote_string` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
338
|
+
`ActiveRecord::StatementInvalid` when it can't connect to the MySQL server.
|
400
339
|
|
401
|
-
*
|
340
|
+
*Jean Boussier*
|
402
341
|
|
403
|
-
|
342
|
+
* Add support for check constraints that are `NOT VALID` via `validate: false` (PostgreSQL-only).
|
404
343
|
|
405
|
-
*
|
344
|
+
*Alex Robbin*
|
406
345
|
|
407
|
-
|
346
|
+
* Ensure the default configuration is considered primary or first for an environment
|
408
347
|
|
409
|
-
|
348
|
+
If a multiple database application provides a configuration named primary, that will be treated as default. In applications that do not have a primary entry, the default database configuration will be the first configuration for an environment.
|
410
349
|
|
411
350
|
*Eileen M. Uchitelle*
|
412
351
|
|
413
|
-
*
|
414
|
-
|
415
|
-
*Kir Shatrov*
|
416
|
-
|
352
|
+
* Allow `where` references association names as joined table name aliases.
|
417
353
|
|
418
|
-
|
419
|
-
|
420
|
-
|
354
|
+
```ruby
|
355
|
+
class Comment < ActiveRecord::Base
|
356
|
+
enum label: [:default, :child]
|
357
|
+
has_many :children, class_name: "Comment", foreign_key: :parent_id
|
358
|
+
end
|
421
359
|
|
422
|
-
|
360
|
+
# ... FROM comments LEFT OUTER JOIN comments children ON ... WHERE children.label = 1
|
361
|
+
Comment.includes(:children).where("children.label": "child")
|
362
|
+
```
|
423
363
|
|
424
364
|
*Ryuta Kamizono*
|
425
365
|
|
426
|
-
*
|
427
|
-
|
428
|
-
*John Crepezzi*, *Eileen Uchitelle*
|
429
|
-
|
430
|
-
* Add a warning for enum elements with 'not_' prefix.
|
431
|
-
|
432
|
-
class Foo
|
433
|
-
enum status: [:sent, :not_sent]
|
434
|
-
end
|
435
|
-
|
436
|
-
*Edu Depetris*
|
366
|
+
* Support storing demodulized class name for polymorphic type.
|
437
367
|
|
438
|
-
|
368
|
+
Before Rails 6.1, storing demodulized class name is supported only for STI type
|
369
|
+
by `store_full_sti_class` class attribute.
|
439
370
|
|
440
|
-
|
371
|
+
Now `store_full_class_name` class attribute can handle both STI and polymorphic types.
|
441
372
|
|
373
|
+
*Ryuta Kamizono*
|
442
374
|
|
443
|
-
|
444
|
-
|
445
|
-
|
375
|
+
* Deprecate `rails db:structure:{load, dump}` tasks and extend
|
376
|
+
`rails db:schema:{load, dump}` tasks to work with either `:ruby` or `:sql` format,
|
377
|
+
depending on `config.active_record.schema_format` configuration value.
|
446
378
|
|
447
|
-
*
|
379
|
+
*fatkodima*
|
448
380
|
|
449
|
-
*
|
381
|
+
* Respect the `select` values for eager loading.
|
450
382
|
|
451
|
-
|
383
|
+
```ruby
|
384
|
+
post = Post.select("UPPER(title) AS title").first
|
385
|
+
post.title # => "WELCOME TO THE WEBLOG"
|
386
|
+
post.body # => ActiveModel::MissingAttributeError
|
387
|
+
|
388
|
+
# Rails 6.0 (ignore the `select` values)
|
389
|
+
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
390
|
+
post.title # => "Welcome to the weblog"
|
391
|
+
post.body # => "Such a lovely day"
|
392
|
+
|
393
|
+
# Rails 6.1 (respect the `select` values)
|
394
|
+
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
395
|
+
post.title # => "WELCOME TO THE WEBLOG"
|
396
|
+
post.body # => ActiveModel::MissingAttributeError
|
397
|
+
```
|
452
398
|
|
453
399
|
*Ryuta Kamizono*
|
454
400
|
|
455
|
-
*
|
456
|
-
|
457
|
-
Fixes #36465.
|
458
|
-
|
459
|
-
*Jeff Doering*
|
401
|
+
* Allow attribute's default to be configured but keeping its own type.
|
460
402
|
|
461
|
-
|
403
|
+
```ruby
|
404
|
+
class Post < ActiveRecord::Base
|
405
|
+
attribute :written_at, default: -> { Time.now.utc }
|
406
|
+
end
|
462
407
|
|
463
|
-
|
408
|
+
# Rails 6.0
|
409
|
+
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
|
464
410
|
|
465
|
-
|
411
|
+
# Rails 6.1
|
412
|
+
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
|
413
|
+
```
|
466
414
|
|
467
|
-
|
415
|
+
*Ryuta Kamizono*
|
468
416
|
|
469
|
-
|
417
|
+
* Allow default to be configured for Enum.
|
470
418
|
|
471
|
-
|
419
|
+
```ruby
|
420
|
+
class Book < ActiveRecord::Base
|
421
|
+
enum status: [:proposed, :written, :published], _default: :published
|
422
|
+
end
|
472
423
|
|
473
|
-
|
424
|
+
Book.new.status # => "published"
|
425
|
+
```
|
474
426
|
|
475
|
-
*
|
427
|
+
*Ryuta Kamizono*
|
476
428
|
|
477
|
-
|
429
|
+
* Deprecate YAML loading from legacy format older than Rails 5.0.
|
478
430
|
|
479
431
|
*Ryuta Kamizono*
|
480
432
|
|
433
|
+
* Added the setting `ActiveRecord::Base.immutable_strings_by_default`, which
|
434
|
+
allows you to specify that all string columns should be frozen unless
|
435
|
+
otherwise specified. This will reduce memory pressure for applications which
|
436
|
+
do not generally mutate string properties of Active Record objects.
|
481
437
|
|
482
|
-
|
438
|
+
*Sean Griffin*, *Ryuta Kamizono*
|
483
439
|
|
484
|
-
*
|
440
|
+
* Deprecate `map!` and `collect!` on `ActiveRecord::Result`.
|
485
441
|
|
486
|
-
*
|
442
|
+
*Ryuta Kamizono*
|
487
443
|
|
488
|
-
*
|
444
|
+
* Support `relation.and` for intersection as Set theory.
|
489
445
|
|
490
446
|
```ruby
|
491
|
-
|
492
|
-
|
493
|
-
```
|
447
|
+
david_and_mary = Author.where(id: [david, mary])
|
448
|
+
mary_and_bob = Author.where(id: [mary, bob])
|
494
449
|
|
495
|
-
|
450
|
+
david_and_mary.merge(mary_and_bob) # => [mary, bob]
|
496
451
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
nor = all.reject { |e|
|
501
|
-
e.estimate_of_type == sapphire.class.polymorphic_name
|
502
|
-
}.reject { |e|
|
503
|
-
e.estimate_of_id == sapphire.id
|
504
|
-
}
|
505
|
-
assert_equal [cars(:honda)], nor
|
506
|
-
|
507
|
-
without_sapphire = PriceEstimate.where.not(
|
508
|
-
estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
|
509
|
-
)
|
510
|
-
assert_equal nor, without_sapphire.map(&:estimate_of)
|
452
|
+
david_and_mary.and(mary_and_bob) # => [mary]
|
453
|
+
david_and_mary.or(mary_and_bob) # => [david, mary, bob]
|
511
454
|
```
|
512
455
|
|
513
|
-
|
514
|
-
|
515
|
-
```ruby
|
516
|
-
sapphire = treasures(:sapphire)
|
456
|
+
*Ryuta Kamizono*
|
517
457
|
|
518
|
-
|
519
|
-
|
458
|
+
* Merging conditions on the same column no longer maintain both conditions,
|
459
|
+
and will be consistently replaced by the latter condition in Rails 6.2.
|
460
|
+
To migrate to Rails 6.2's behavior, use `relation.merge(other, rewhere: true)`.
|
520
461
|
|
521
|
-
|
522
|
-
|
523
|
-
)
|
524
|
-
assert_equal nand, without_sapphire.map(&:estimate_of)
|
525
|
-
```
|
462
|
+
```ruby
|
463
|
+
# Rails 6.1 (IN clause is replaced by merger side equality condition)
|
464
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
526
465
|
|
527
|
-
|
466
|
+
# Rails 6.1 (both conflict conditions exists, deprecated)
|
467
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
|
528
468
|
|
529
|
-
|
469
|
+
# Rails 6.1 with rewhere to migrate to Rails 6.2's behavior
|
470
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
|
530
471
|
|
531
|
-
|
472
|
+
# Rails 6.2 (same behavior with IN clause, mergee side condition is consistently replaced)
|
473
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
474
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
475
|
+
```
|
532
476
|
|
533
477
|
*Ryuta Kamizono*
|
534
478
|
|
535
|
-
*
|
536
|
-
the versioned entries in `ActiveSupport::Cache`. This also means that
|
537
|
-
`ActiveRecord::Relation#cache_key` will now return a stable key that does not
|
538
|
-
include the max timestamp or count any more.
|
479
|
+
* Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case.
|
539
480
|
|
540
|
-
|
541
|
-
cache keys with timestamps until you set `ActiveRecord::Base.collection_cache_versioning = true`.
|
542
|
-
That's the setting for all new apps on Rails 6.0+
|
481
|
+
*Peter Fry*
|
543
482
|
|
544
|
-
|
483
|
+
* Resolve issue with insert_all unique_by option when used with expression index.
|
545
484
|
|
546
|
-
|
485
|
+
When the `:unique_by` option of `ActiveRecord::Persistence.insert_all` and
|
486
|
+
`ActiveRecord::Persistence.upsert_all` was used with the name of an expression index, an error
|
487
|
+
was raised. Adding a guard around the formatting behavior for the `:unique_by` corrects this.
|
547
488
|
|
548
|
-
|
489
|
+
Usage:
|
549
490
|
|
550
|
-
|
491
|
+
```ruby
|
492
|
+
create_table :books, id: :integer, force: true do |t|
|
493
|
+
t.column :name, :string
|
494
|
+
t.index "lower(name)", unique: true
|
495
|
+
end
|
551
496
|
|
552
|
-
|
553
|
-
|
497
|
+
Book.insert_all [{ name: "MyTest" }], unique_by: :index_books_on_lower_name
|
498
|
+
```
|
554
499
|
|
555
|
-
|
500
|
+
Fixes #39516.
|
556
501
|
|
557
|
-
*
|
502
|
+
*Austen Madden*
|
558
503
|
|
559
|
-
|
504
|
+
* Add basic support for CHECK constraints to database migrations.
|
560
505
|
|
561
|
-
|
506
|
+
Usage:
|
562
507
|
|
563
|
-
|
508
|
+
```ruby
|
509
|
+
add_check_constraint :products, "price > 0", name: "price_check"
|
510
|
+
remove_check_constraint :products, name: "price_check"
|
511
|
+
```
|
564
512
|
|
565
|
-
|
566
|
-
associations, the callback for a `has_many` association was run while
|
567
|
-
another instance of the same callback on the same association hadn't
|
568
|
-
finished running. When control returned to the first instance of the
|
569
|
-
callback, the instance variable had changed, and subsequent associated
|
570
|
-
records weren't saved correctly. Specifically, the ID field for the
|
571
|
-
`belongs_to` corresponding to the `has_many` was `nil`.
|
513
|
+
*fatkodima*
|
572
514
|
|
573
|
-
|
515
|
+
* Add `ActiveRecord::Base.strict_loading_by_default` and `ActiveRecord::Base.strict_loading_by_default=`
|
516
|
+
to enable/disable strict_loading mode by default for a model. The configuration's value is
|
517
|
+
inheritable by subclasses, but they can override that value and it will not impact parent class.
|
574
518
|
|
575
|
-
|
519
|
+
Usage:
|
576
520
|
|
577
|
-
|
521
|
+
```ruby
|
522
|
+
class Developer < ApplicationRecord
|
523
|
+
self.strict_loading_by_default = true
|
578
524
|
|
579
|
-
|
525
|
+
has_many :projects
|
526
|
+
end
|
580
527
|
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
add_column :items, :attr3, :integer, limit: 10 # => ActiveRecordError
|
585
|
-
add_column :items, :attr4, :datetime, precision: 10 # => ActiveRecordError
|
528
|
+
dev = Developer.first
|
529
|
+
dev.projects.first
|
530
|
+
# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
|
586
531
|
```
|
587
532
|
|
588
|
-
|
533
|
+
*bogdanvlviv*
|
589
534
|
|
590
|
-
|
591
|
-
add_column :items, :attr1, :binary, size: 10 # => ArgumentError
|
592
|
-
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
|
593
|
-
add_column :items, :attr3, :integer, limit: 10 # => ArgumentError
|
594
|
-
add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
|
595
|
-
```
|
535
|
+
* Deprecate passing an Active Record object to `quote`/`type_cast` directly.
|
596
536
|
|
597
537
|
*Ryuta Kamizono*
|
598
538
|
|
599
|
-
*
|
600
|
-
whether preloaded / eager loaded or not, with the exception of `unscoped`.
|
539
|
+
* Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic.
|
601
540
|
|
602
541
|
Before:
|
603
542
|
|
604
543
|
```ruby
|
605
|
-
|
606
|
-
Comment.find(1).post # => nil
|
607
|
-
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
608
|
-
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
544
|
+
create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
609
545
|
end
|
610
546
|
```
|
611
547
|
|
612
548
|
After:
|
613
549
|
|
614
550
|
```ruby
|
615
|
-
|
616
|
-
Comment.find(1).post # => #<Post id: 1, ...>
|
617
|
-
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
618
|
-
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
551
|
+
create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
619
552
|
end
|
620
553
|
```
|
621
554
|
|
622
|
-
Fixes #34638, #35398.
|
623
|
-
|
624
555
|
*Ryuta Kamizono*
|
625
556
|
|
626
|
-
*
|
627
|
-
|
628
|
-
Runs `db:migrate` if the database exists or `db:setup` if it doesn't.
|
629
|
-
|
630
|
-
*Roberto Miranda*
|
631
|
-
|
632
|
-
* Add `after_save_commit` callback as shortcut for `after_commit :hook, on: [ :create, :update ]`.
|
557
|
+
* Added delegated type as an alternative to single-table inheritance for representing class hierarchies.
|
558
|
+
See ActiveRecord::DelegatedType for the full description.
|
633
559
|
|
634
560
|
*DHH*
|
635
561
|
|
636
|
-
*
|
637
|
-
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
638
|
-
|
639
|
-
Fixes #33249.
|
640
|
-
|
641
|
-
*Ryan H. Kerr*
|
562
|
+
* Deprecate aggregations with group by duplicated fields.
|
642
563
|
|
643
|
-
|
644
|
-
|
645
|
-
```
|
646
|
-
account.memberships.extract_associated(:user)
|
647
|
-
# => Returns collection of User records
|
648
|
-
```
|
649
|
-
|
650
|
-
*DHH*
|
564
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:group)` to deduplicate group fields.
|
651
565
|
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
#
|
566
|
+
```ruby
|
567
|
+
accounts = Account.group(:firm_id)
|
568
|
+
|
569
|
+
# duplicated group fields, deprecated.
|
570
|
+
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
|
571
|
+
# => {
|
572
|
+
# [1, 1] => 50,
|
573
|
+
# [2, 2] => 60
|
574
|
+
# }
|
575
|
+
|
576
|
+
# use `uniq!(:group)` to deduplicate group fields.
|
577
|
+
accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
|
578
|
+
# => {
|
579
|
+
# 1 => 50,
|
580
|
+
# 2 => 60
|
581
|
+
# }
|
659
582
|
```
|
660
583
|
|
661
|
-
This can be useful in instrumentation or other analysis of issued queries.
|
662
|
-
|
663
|
-
*Matt Yoho*
|
664
|
-
|
665
|
-
* Support Optimizer Hints.
|
666
|
-
|
667
|
-
In most databases, a way to control the optimizer is by using optimizer hints,
|
668
|
-
which can be specified within individual statements.
|
669
|
-
|
670
|
-
Example (for MySQL):
|
671
|
-
|
672
|
-
Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
|
673
|
-
# SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
|
674
|
-
|
675
|
-
Example (for PostgreSQL with pg_hint_plan):
|
676
|
-
|
677
|
-
Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
|
678
|
-
# SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
679
|
-
|
680
|
-
See also:
|
681
|
-
|
682
|
-
* https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html
|
683
|
-
* https://pghintplan.osdn.jp/pg_hint_plan.html
|
684
|
-
* https://docs.oracle.com/en/database/oracle/oracle-database/12.2/tgsql/influencing-the-optimizer.html
|
685
|
-
* https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-2017
|
686
|
-
* https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.admin.perf.doc/doc/c0070117.html
|
687
|
-
|
688
584
|
*Ryuta Kamizono*
|
689
585
|
|
690
|
-
*
|
586
|
+
* Deprecate duplicated query annotations.
|
691
587
|
|
692
|
-
|
588
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:annotate)` to deduplicate query annotations.
|
693
589
|
|
694
|
-
```
|
695
|
-
|
696
|
-
attribute :user_defined_text, :text
|
697
|
-
end
|
698
|
-
|
699
|
-
Post.new(user_defined_text: "false").user_defined_text? # => true
|
700
|
-
```
|
701
|
-
|
702
|
-
*Yuji Kamijima*
|
703
|
-
|
704
|
-
* Quote empty ranges like other empty enumerables.
|
705
|
-
|
706
|
-
*Patrick Rebsch*
|
707
|
-
|
708
|
-
* Add `insert_all`/`insert_all!`/`upsert_all` methods to `ActiveRecord::Persistence`,
|
709
|
-
allowing bulk inserts akin to the bulk updates provided by `update_all` and
|
710
|
-
bulk deletes by `delete_all`.
|
711
|
-
|
712
|
-
Supports skipping or upserting duplicates through the `ON CONFLICT` syntax
|
713
|
-
for PostgreSQL (9.5+) and SQLite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
|
714
|
-
for MySQL.
|
715
|
-
|
716
|
-
*Bob Lail*
|
717
|
-
|
718
|
-
* Add `rails db:seed:replant` that truncates tables of each database
|
719
|
-
for current environment and loads the seeds.
|
720
|
-
|
721
|
-
*bogdanvlviv*, *DHH*
|
722
|
-
|
723
|
-
* Add `ActiveRecord::Base.connection.truncate` for SQLite3 adapter.
|
724
|
-
|
725
|
-
*bogdanvlviv*
|
590
|
+
```ruby
|
591
|
+
accounts = Account.where(id: [1, 2]).annotate("david and mary")
|
726
592
|
|
727
|
-
|
593
|
+
# duplicated annotations, deprecated.
|
594
|
+
accounts.merge(accounts.rewhere(id: 3))
|
595
|
+
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */ /* david and mary */
|
728
596
|
|
729
|
-
|
730
|
-
|
731
|
-
|
597
|
+
# use `uniq!(:annotate)` to deduplicate annotations.
|
598
|
+
accounts.merge(accounts.rewhere(id: 3)).uniq!(:annotate)
|
599
|
+
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */
|
600
|
+
```
|
732
601
|
|
733
602
|
*Ryuta Kamizono*
|
734
603
|
|
735
|
-
*
|
604
|
+
* Resolve conflict between counter cache and optimistic locking.
|
605
|
+
|
606
|
+
Bump an Active Record instance's lock version after updating its counter
|
607
|
+
cache. This avoids raising an unnecessary `ActiveRecord::StaleObjectError`
|
608
|
+
upon subsequent transactions by maintaining parity with the corresponding
|
609
|
+
database record's `lock_version` column.
|
736
610
|
|
737
|
-
Fixes #
|
611
|
+
Fixes #16449.
|
738
612
|
|
739
|
-
*
|
613
|
+
*Aaron Lipman*
|
740
614
|
|
741
|
-
*
|
615
|
+
* Support merging option `:rewhere` to allow mergee side condition to be replaced exactly.
|
742
616
|
|
743
|
-
|
617
|
+
```ruby
|
618
|
+
david_and_mary = Author.where(id: david.id..mary.id)
|
744
619
|
|
745
|
-
|
746
|
-
|
747
|
-
end
|
620
|
+
# both conflict conditions exists
|
621
|
+
david_and_mary.merge(Author.where(id: bob)) # => []
|
748
622
|
|
749
|
-
|
750
|
-
|
751
|
-
Post.not_trashed # => where.not(status: :trashed)
|
623
|
+
# mergee side condition is replaced by rewhere
|
624
|
+
david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
|
752
625
|
|
753
|
-
|
626
|
+
# mergee side condition is replaced by rewhere option
|
627
|
+
david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
|
628
|
+
```
|
754
629
|
|
755
|
-
*
|
630
|
+
*Ryuta Kamizono*
|
756
631
|
|
757
|
-
|
632
|
+
* Add support for finding records based on signed ids, which are tamper-proof, verified ids that can be
|
633
|
+
set to expire and scoped with a purpose. This is particularly useful for things like password reset
|
634
|
+
or email verification, where you want the bearer of the signed id to be able to interact with the
|
635
|
+
underlying record, but usually only within a certain time period.
|
758
636
|
|
759
|
-
|
637
|
+
```ruby
|
638
|
+
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
|
760
639
|
|
640
|
+
User.find_signed signed_id # => nil, since the purpose does not match
|
761
641
|
|
762
|
-
|
642
|
+
travel 16.minutes
|
643
|
+
User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
|
763
644
|
|
764
|
-
|
645
|
+
travel_back
|
646
|
+
User.find_signed signed_id, purpose: :password_reset # => User.first
|
765
647
|
|
648
|
+
User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
|
649
|
+
```
|
766
650
|
|
767
|
-
|
651
|
+
*DHH*
|
768
652
|
|
769
|
-
*
|
653
|
+
* Support `ALGORITHM = INSTANT` DDL option for index operations on MySQL.
|
770
654
|
|
771
655
|
*Ryuta Kamizono*
|
772
656
|
|
773
|
-
*
|
657
|
+
* Fix index creation to preserve index comment in bulk change table on MySQL.
|
774
658
|
|
775
659
|
*Ryuta Kamizono*
|
776
660
|
|
777
|
-
*
|
661
|
+
* Allow `unscope` to be aware of table name qualified values.
|
778
662
|
|
779
|
-
|
663
|
+
It is possible to unscope only the column in the specified table.
|
780
664
|
|
781
|
-
|
665
|
+
```ruby
|
666
|
+
posts = Post.joins(:comments).group(:"posts.hidden")
|
667
|
+
posts = posts.where("posts.hidden": false, "comments.hidden": false)
|
782
668
|
|
783
|
-
|
784
|
-
|
669
|
+
posts.count
|
670
|
+
# => { false => 10 }
|
785
671
|
|
786
|
-
|
672
|
+
# unscope both hidden columns
|
673
|
+
posts.unscope(where: :hidden).count
|
674
|
+
# => { false => 11, true => 1 }
|
787
675
|
|
788
|
-
|
789
|
-
|
676
|
+
# unscope only comments.hidden column
|
677
|
+
posts.unscope(where: :"comments.hidden").count
|
678
|
+
# => { false => 11 }
|
679
|
+
```
|
790
680
|
|
791
|
-
|
792
|
-
david.posts.destroy_by(id: [1, 2, 3])
|
681
|
+
*Ryuta Kamizono*, *Slava Korolev*
|
793
682
|
|
794
|
-
|
795
|
-
`delete_all` on the matched records.
|
683
|
+
* Fix `rewhere` to truly overwrite collided where clause by new where clause.
|
796
684
|
|
797
|
-
|
685
|
+
```ruby
|
686
|
+
steve = Person.find_by(name: "Steve")
|
687
|
+
david = Author.find_by(name: "David")
|
798
688
|
|
799
|
-
|
800
|
-
Person.delete_by(name: 'David', rating: 4)
|
689
|
+
relation = Essay.where(writer: steve)
|
801
690
|
|
802
|
-
|
803
|
-
|
691
|
+
# Before
|
692
|
+
relation.rewhere(writer: david).to_a # => []
|
804
693
|
|
805
|
-
|
694
|
+
# After
|
695
|
+
relation.rewhere(writer: david).to_a # => [david]
|
696
|
+
```
|
806
697
|
|
807
|
-
*
|
698
|
+
*Ryuta Kamizono*
|
808
699
|
|
809
|
-
|
700
|
+
* Inspect time attributes with subsec and time zone offset.
|
810
701
|
|
811
|
-
|
702
|
+
```ruby
|
703
|
+
p Knot.create
|
704
|
+
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000 +0000">
|
705
|
+
```
|
812
706
|
|
813
|
-
*
|
707
|
+
*akinomaeni*, *Jonathan Hefner*
|
708
|
+
|
709
|
+
* Deprecate passing a column to `type_cast`.
|
814
710
|
|
815
711
|
*Ryuta Kamizono*
|
816
712
|
|
817
|
-
* Deprecate
|
818
|
-
regarded as leaked. Use `klass.unscoped` to avoid the leaking scope.
|
713
|
+
* Deprecate `in_clause_length` and `allowed_index_name_length` in `DatabaseLimits`.
|
819
714
|
|
820
715
|
*Ryuta Kamizono*
|
821
716
|
|
822
|
-
*
|
823
|
-
|
824
|
-
Adds a middleware and configuration options that can be used in your
|
825
|
-
application to automatically switch between the writing and reading
|
826
|
-
database connections.
|
717
|
+
* Support bulk insert/upsert on relation to preserve scope values.
|
827
718
|
|
828
|
-
|
829
|
-
a write in the last 2 seconds, otherwise they will read from the primary.
|
830
|
-
Non-get requests will always write to the primary. The middleware accepts
|
831
|
-
an argument for a Resolver class and an Operations class where you are able
|
832
|
-
to change how the auto-switcher works to be most beneficial for your
|
833
|
-
application.
|
719
|
+
*Josef Šimánek*, *Ryuta Kamizono*
|
834
720
|
|
835
|
-
|
836
|
-
configuration options:
|
721
|
+
* Preserve column comment value on changing column name on MySQL.
|
837
722
|
|
838
|
-
|
839
|
-
config.active_record.database_selector = { delay: 2.seconds }
|
840
|
-
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
|
841
|
-
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
|
842
|
-
```
|
723
|
+
*Islam Taha*
|
843
724
|
|
844
|
-
|
845
|
-
configuration options:
|
725
|
+
* Add support for `if_exists` option for removing an index.
|
846
726
|
|
847
|
-
|
848
|
-
config.active_record.database_selector = { delay: 10.seconds }
|
849
|
-
config.active_record.database_resolver = MyResolver
|
850
|
-
config.active_record.database_resolver_context = MyResolver::MyCookies
|
851
|
-
```
|
727
|
+
The `remove_index` method can take an `if_exists` option. If this is set to true an error won't be raised if the index doesn't exist.
|
852
728
|
|
853
729
|
*Eileen M. Uchitelle*
|
854
730
|
|
855
|
-
*
|
731
|
+
* Remove ibm_db, informix, mssql, oracle, and oracle12 Arel visitors which are not used in the code base.
|
856
732
|
|
857
733
|
*Ryuta Kamizono*
|
858
734
|
|
859
|
-
*
|
735
|
+
* Prevent `build_association` from `touching` a parent record if the record isn't persisted for `has_one` associations.
|
860
736
|
|
861
|
-
|
737
|
+
Fixes #38219.
|
862
738
|
|
739
|
+
*Josh Brody*
|
863
740
|
|
864
|
-
|
741
|
+
* Add support for `if_not_exists` option for adding index.
|
865
742
|
|
866
|
-
|
743
|
+
The `add_index` method respects `if_not_exists` option. If it is set to true
|
744
|
+
index won't be added.
|
867
745
|
|
868
|
-
|
746
|
+
Usage:
|
869
747
|
|
870
|
-
|
748
|
+
```ruby
|
749
|
+
add_index :users, :account_id, if_not_exists: true
|
750
|
+
```
|
871
751
|
|
872
|
-
|
752
|
+
The `if_not_exists` option passed to `create_table` also gets propagated to indexes
|
753
|
+
created within that migration so that if table and its indexes exist then there is no
|
754
|
+
attempt to create them again.
|
873
755
|
|
874
|
-
*
|
756
|
+
*Prathamesh Sonpatki*
|
875
757
|
|
876
|
-
|
758
|
+
* Add `ActiveRecord::Base#previously_new_record?` to show if a record was new before the last save.
|
877
759
|
|
878
|
-
*
|
760
|
+
*Tom Ward*
|
879
761
|
|
880
|
-
|
762
|
+
* Support descending order for `find_each`, `find_in_batches`, and `in_batches`.
|
881
763
|
|
882
|
-
|
764
|
+
Batch processing methods allow you to work with the records in batches, greatly reducing memory consumption, but records are always batched from oldest id to newest.
|
883
765
|
|
884
|
-
|
766
|
+
This change allows reversing the order, batching from newest to oldest. This is useful when you need to process newer batches of records first.
|
885
767
|
|
886
|
-
|
768
|
+
Pass `order: :desc` to yield batches in descending order. The default remains `order: :asc`.
|
887
769
|
|
888
|
-
|
770
|
+
```ruby
|
771
|
+
Person.find_each(order: :desc) do |person|
|
772
|
+
person.party_all_night!
|
773
|
+
end
|
774
|
+
```
|
889
775
|
|
890
|
-
*
|
776
|
+
*Alexey Vasiliev*
|
891
777
|
|
892
|
-
|
778
|
+
* Fix `insert_all` with enum values.
|
893
779
|
|
894
|
-
|
780
|
+
Fixes #38716.
|
895
781
|
|
896
|
-
*
|
782
|
+
*Joel Blum*
|
897
783
|
|
898
|
-
*
|
784
|
+
* Add support for `db:rollback:name` for multiple database applications.
|
899
785
|
|
900
|
-
|
786
|
+
Multiple database applications will now raise if `db:rollback` is call and recommend using the `db:rollback:[NAME]` to rollback migrations.
|
901
787
|
|
902
|
-
*
|
788
|
+
*Eileen M. Uchitelle*
|
903
789
|
|
904
|
-
|
790
|
+
* `Relation#pick` now uses already loaded results instead of making another query.
|
905
791
|
|
906
|
-
*
|
792
|
+
*Eugene Kenny*
|
907
793
|
|
908
|
-
|
794
|
+
* Deprecate using `return`, `break` or `throw` to exit a transaction block after writes.
|
909
795
|
|
910
|
-
*
|
796
|
+
*Dylan Thacker-Smith*
|
911
797
|
|
912
|
-
|
798
|
+
* Dump the schema or structure of a database when calling `db:migrate:name`.
|
913
799
|
|
914
|
-
|
800
|
+
In previous versions of Rails, `rails db:migrate` would dump the schema of the database. In Rails 6, that holds true (`rails db:migrate` dumps all databases' schemas), but `rails db:migrate:name` does not share that behavior.
|
915
801
|
|
916
|
-
|
802
|
+
Going forward, calls to `rails db:migrate:name` will dump the schema (or structure) of the database being migrated.
|
917
803
|
|
918
|
-
*
|
804
|
+
*Kyle Thompson*
|
919
805
|
|
920
|
-
|
806
|
+
* Reset the `ActiveRecord::Base` connection after `rails db:migrate:name`.
|
921
807
|
|
922
|
-
|
808
|
+
When `rails db:migrate` has finished, it ensures the `ActiveRecord::Base` connection is reset to its original configuration. Going forward, `rails db:migrate:name` will have the same behavior.
|
923
809
|
|
924
|
-
*
|
810
|
+
*Kyle Thompson*
|
925
811
|
|
926
|
-
|
812
|
+
* Disallow calling `connected_to` on subclasses of `ActiveRecord::Base`.
|
927
813
|
|
928
|
-
|
814
|
+
Behavior has not changed here but the previous API could be misleading to people who thought it would switch connections for only that class. `connected_to` switches the context from which we are getting connections, not the connections themselves.
|
929
815
|
|
930
|
-
*
|
816
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
931
817
|
|
932
|
-
*
|
818
|
+
* Add support for horizontal sharding to `connects_to` and `connected_to`.
|
933
819
|
|
934
|
-
|
820
|
+
Applications can now connect to multiple shards and switch between their shards in an application. Note that the shard swapping is still a manual process as this change does not include an API for automatic shard swapping.
|
935
821
|
|
936
|
-
|
822
|
+
Usage:
|
937
823
|
|
938
|
-
|
939
|
-
format for InnoDB tables. The default setting is `DYNAMIC`.
|
940
|
-
The row format is required for indexing on `varchar(255)` with `utf8mb4` columns.
|
824
|
+
Given the following configuration:
|
941
825
|
|
942
|
-
|
826
|
+
```yaml
|
827
|
+
# config/database.yml
|
828
|
+
production:
|
829
|
+
primary:
|
830
|
+
database: my_database
|
831
|
+
primary_shard_one:
|
832
|
+
database: my_database_shard_one
|
833
|
+
```
|
943
834
|
|
944
|
-
|
835
|
+
Connect to multiple shards:
|
945
836
|
|
946
|
-
|
837
|
+
```ruby
|
838
|
+
class ApplicationRecord < ActiveRecord::Base
|
839
|
+
self.abstract_class = true
|
947
840
|
|
948
|
-
|
841
|
+
connects_to shards: {
|
842
|
+
default: { writing: :primary },
|
843
|
+
shard_one: { writing: :primary_shard_one }
|
844
|
+
}
|
845
|
+
```
|
949
846
|
|
950
|
-
|
847
|
+
Swap between shards in your controller / model code:
|
951
848
|
|
952
|
-
|
849
|
+
```ruby
|
850
|
+
ActiveRecord::Base.connected_to(shard: :shard_one) do
|
851
|
+
# Read from shard one
|
852
|
+
end
|
853
|
+
```
|
953
854
|
|
954
|
-
|
855
|
+
The horizontal sharding API also supports read replicas. See guides for more details.
|
955
856
|
|
956
|
-
*
|
857
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
957
858
|
|
958
|
-
|
859
|
+
* Deprecate `spec_name` in favor of `name` on database configurations.
|
959
860
|
|
960
|
-
|
861
|
+
The accessors for `spec_name` on `configs_for` and `DatabaseConfig` are deprecated. Please use `name` instead.
|
961
862
|
|
962
|
-
|
963
|
-
you're building out multiple databases and want to make sure you're not sending
|
964
|
-
writes when you want a read.
|
863
|
+
Deprecated behavior:
|
965
864
|
|
966
|
-
|
967
|
-
|
968
|
-
|
865
|
+
```ruby
|
866
|
+
db_config = ActiveRecord::Base.configs_for(env_name: "development", spec_name: "primary")
|
867
|
+
db_config.spec_name
|
868
|
+
```
|
969
869
|
|
970
|
-
|
971
|
-
read-only queries without opening a second connection. One purpose of this is to
|
972
|
-
catch accidental writes, not all writes.
|
870
|
+
New behavior:
|
973
871
|
|
974
|
-
|
872
|
+
```ruby
|
873
|
+
db_config = ActiveRecord::Base.configs_for(env_name: "development", name: "primary")
|
874
|
+
db_config.name
|
875
|
+
```
|
975
876
|
|
976
|
-
*
|
877
|
+
*Eileen M. Uchitelle*
|
977
878
|
|
978
|
-
|
879
|
+
* Add additional database-specific rake tasks for multi-database users.
|
979
880
|
|
980
|
-
|
881
|
+
Previously, `rails db:create`, `rails db:drop`, and `rails db:migrate` were the only rails tasks that could operate on a single
|
882
|
+
database. For example:
|
981
883
|
|
982
|
-
|
884
|
+
```
|
885
|
+
rails db:create
|
886
|
+
rails db:create:primary
|
887
|
+
rails db:create:animals
|
888
|
+
rails db:drop
|
889
|
+
rails db:drop:primary
|
890
|
+
rails db:drop:animals
|
891
|
+
rails db:migrate
|
892
|
+
rails db:migrate:primary
|
893
|
+
rails db:migrate:animals
|
894
|
+
```
|
983
895
|
|
984
|
-
|
896
|
+
With these changes, `rails db:schema:dump`, `rails db:schema:load`, `rails db:structure:dump`, `rails db:structure:load` and
|
897
|
+
`rails db:test:prepare` can additionally operate on a single database. For example:
|
985
898
|
|
986
|
-
|
899
|
+
```
|
900
|
+
rails db:schema:dump
|
901
|
+
rails db:schema:dump:primary
|
902
|
+
rails db:schema:dump:animals
|
903
|
+
rails db:schema:load
|
904
|
+
rails db:schema:load:primary
|
905
|
+
rails db:schema:load:animals
|
906
|
+
rails db:structure:dump
|
907
|
+
rails db:structure:dump:primary
|
908
|
+
rails db:structure:dump:animals
|
909
|
+
rails db:structure:load
|
910
|
+
rails db:structure:load:primary
|
911
|
+
rails db:structure:load:animals
|
912
|
+
rails db:test:prepare
|
913
|
+
rails db:test:prepare:primary
|
914
|
+
rails db:test:prepare:animals
|
915
|
+
```
|
987
916
|
|
988
|
-
|
989
|
-
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
917
|
+
*Kyle Thompson*
|
990
918
|
|
991
|
-
|
992
|
-
class DeveloperName < ActiveRecord::Type::String
|
993
|
-
def deserialize(value)
|
994
|
-
"Developer: #{value}"
|
995
|
-
end
|
996
|
-
end
|
919
|
+
* Add support for `strict_loading` mode on association declarations.
|
997
920
|
|
998
|
-
|
999
|
-
self.table_name = "developers"
|
921
|
+
Raise an error if attempting to load a record from an association that has been marked as `strict_loading` unless it was explicitly eager loaded.
|
1000
922
|
|
1001
|
-
|
923
|
+
Usage:
|
1002
924
|
|
1003
|
-
|
925
|
+
```ruby
|
926
|
+
class Developer < ApplicationRecord
|
927
|
+
has_many :projects, strict_loading: true
|
1004
928
|
end
|
1005
929
|
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
loaded_developer = AttributedDeveloper.where(id: developer.id).select("*").first
|
1010
|
-
puts loaded_developer.name # should be "Developer: name" but it's just "name"
|
930
|
+
dev = Developer.first
|
931
|
+
dev.projects.first
|
932
|
+
# => ActiveRecord::StrictLoadingViolationError: The projects association is marked as strict_loading and cannot be lazily loaded.
|
1011
933
|
```
|
1012
934
|
|
1013
|
-
*
|
1014
|
-
|
1015
|
-
* Make the implicit order column configurable.
|
1016
|
-
|
1017
|
-
When calling ordered finder methods such as `first` or `last` without an
|
1018
|
-
explicit order clause, ActiveRecord sorts records by primary key. This can
|
1019
|
-
result in unpredictable and surprising behaviour when the primary key is
|
1020
|
-
not an auto-incrementing integer, for example when it's a UUID. This change
|
1021
|
-
makes it possible to override the column used for implicit ordering such
|
1022
|
-
that `first` and `last` will return more predictable results.
|
1023
|
-
|
1024
|
-
Example:
|
1025
|
-
|
1026
|
-
class Project < ActiveRecord::Base
|
1027
|
-
self.implicit_order_column = "created_at"
|
1028
|
-
end
|
935
|
+
*Kevin Deisz*
|
1029
936
|
|
1030
|
-
|
937
|
+
* Add support for `strict_loading` mode to prevent lazy loading of records.
|
1031
938
|
|
1032
|
-
|
939
|
+
Raise an error if a parent record is marked as `strict_loading` and attempts to lazily load its associations. This is useful for finding places you may want to preload an association and avoid additional queries.
|
1033
940
|
|
1034
|
-
|
941
|
+
Usage:
|
1035
942
|
|
1036
|
-
|
943
|
+
```ruby
|
944
|
+
dev = Developer.strict_loading.first
|
945
|
+
dev.audit_logs.to_a
|
946
|
+
# => ActiveRecord::StrictLoadingViolationError: Developer is marked as strict_loading and AuditLog cannot be lazily loaded.
|
947
|
+
```
|
1037
948
|
|
1038
|
-
*
|
949
|
+
*Eileen M. Uchitelle*, *Aaron Patterson*
|
1039
950
|
|
1040
|
-
*
|
951
|
+
* Add support for PostgreSQL 11+ partitioned indexes when using `upsert_all`.
|
1041
952
|
|
1042
|
-
|
953
|
+
*Sebastián Palma*
|
1043
954
|
|
1044
|
-
|
955
|
+
* Adds support for `if_not_exists` to `add_column` and `if_exists` to `remove_column`.
|
1045
956
|
|
1046
|
-
|
957
|
+
Applications can set their migrations to ignore exceptions raised when adding a column that already exists or when removing a column that does not exist.
|
1047
958
|
|
1048
|
-
Example:
|
959
|
+
Example Usage:
|
1049
960
|
|
1050
|
-
```
|
1051
|
-
class
|
1052
|
-
def
|
1053
|
-
|
961
|
+
```ruby
|
962
|
+
class AddColumnTitle < ActiveRecord::Migration[6.1]
|
963
|
+
def change
|
964
|
+
add_column :posts, :title, :string, if_not_exists: true
|
1054
965
|
end
|
1055
966
|
end
|
1056
967
|
```
|
1057
968
|
|
1058
|
-
|
969
|
+
```ruby
|
970
|
+
class RemoveColumnTitle < ActiveRecord::Migration[6.1]
|
971
|
+
def change
|
972
|
+
remove_column :posts, :title, if_exists: true
|
973
|
+
end
|
974
|
+
end
|
975
|
+
```
|
1059
976
|
|
1060
|
-
*
|
977
|
+
*Eileen M. Uchitelle*
|
1061
978
|
|
1062
|
-
|
979
|
+
* Regexp-escape table name for MS SQL Server.
|
1063
980
|
|
1064
|
-
|
1065
|
-
t.string :title
|
1066
|
-
end
|
981
|
+
Add `Regexp.escape` to one method in ActiveRecord, so that table names with regular expression characters in them work as expected. Since MS SQL Server uses "[" and "]" to quote table and column names, and those characters are regular expression characters, methods like `pluck` and `select` fail in certain cases when used with the MS SQL Server adapter.
|
1067
982
|
|
1068
|
-
|
983
|
+
*Larry Reid*
|
1069
984
|
|
1070
|
-
|
1071
|
-
...
|
1072
|
-
)
|
985
|
+
* Store advisory locks on their own named connection.
|
1073
986
|
|
1074
|
-
|
1075
|
-
exception whereas `if_not_exists: true` does nothing.
|
987
|
+
Previously advisory locks were taken out against a connection when a migration started. This works fine in single database applications but doesn't work well when migrations need to open new connections which results in the lock getting dropped.
|
1076
988
|
|
1077
|
-
|
989
|
+
In order to fix this we are storing the advisory lock on a new connection with the connection specification name `AdvisoryLockBase`. The caveat is that we need to maintain at least 2 connections to a database while migrations are running in order to do this.
|
1078
990
|
|
1079
|
-
*
|
991
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1080
992
|
|
1081
|
-
|
993
|
+
* Allow schema cache path to be defined in the database configuration file.
|
1082
994
|
|
1083
|
-
|
995
|
+
For example:
|
1084
996
|
|
1085
|
-
|
997
|
+
```yaml
|
998
|
+
development:
|
999
|
+
adapter: postgresql
|
1000
|
+
database: blog_development
|
1001
|
+
pool: 5
|
1002
|
+
schema_cache_path: tmp/schema/main.yml
|
1003
|
+
```
|
1086
1004
|
|
1087
|
-
*
|
1088
|
-
if the attribute does not exist.
|
1005
|
+
*Katrina Owen*
|
1089
1006
|
|
1090
|
-
|
1007
|
+
* Deprecate `#remove_connection` in favor of `#remove_connection_pool` when called on the handler.
|
1091
1008
|
|
1092
|
-
|
1009
|
+
`#remove_connection` is deprecated in order to support returning a `DatabaseConfig` object instead of a `Hash`. Use `#remove_connection_pool`, `#remove_connection` will be removed in 6.2.
|
1093
1010
|
|
1094
|
-
|
1095
|
-
User.connected_to(database: { writing: "postgres://foo" }) do
|
1096
|
-
User.create!(name: "Gannon")
|
1097
|
-
end
|
1011
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1098
1012
|
|
1099
|
-
|
1100
|
-
User.connected_to(database: { reading: config }) do
|
1101
|
-
User.count
|
1102
|
-
end
|
1103
|
-
````
|
1013
|
+
* Deprecate `#default_hash` and it's alias `#[]` on database configurations.
|
1104
1014
|
|
1105
|
-
|
1015
|
+
Applications should use `configs_for`. `#default_hash` and `#[]` will be removed in 6.2.
|
1106
1016
|
|
1107
|
-
*
|
1017
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1108
1018
|
|
1109
|
-
|
1019
|
+
* Add scale support to `ActiveRecord::Validations::NumericalityValidator`.
|
1110
1020
|
|
1111
|
-
|
1021
|
+
*Gannon McGibbon*
|
1112
1022
|
|
1113
|
-
|
1023
|
+
* Find orphans by looking for missing relations through chaining `where.missing`:
|
1114
1024
|
|
1115
|
-
|
1025
|
+
Before:
|
1116
1026
|
|
1117
|
-
|
1118
|
-
|
1027
|
+
```ruby
|
1028
|
+
Post.left_joins(:author).where(authors: { id: nil })
|
1029
|
+
```
|
1119
1030
|
|
1120
|
-
|
1031
|
+
After:
|
1121
1032
|
|
1122
|
-
|
1033
|
+
```ruby
|
1034
|
+
Post.where.missing(:author)
|
1035
|
+
```
|
1123
1036
|
|
1124
|
-
*
|
1037
|
+
*Tom Rossi*
|
1125
1038
|
|
1126
|
-
|
1039
|
+
* Ensure `:reading` connections always raise if a write is attempted.
|
1127
1040
|
|
1128
|
-
|
1041
|
+
Now Rails will raise an `ActiveRecord::ReadOnlyError` if any connection on the reading handler attempts to make a write. If your reading role needs to write you should name the role something other than `:reading`.
|
1129
1042
|
|
1130
|
-
*
|
1043
|
+
*Eileen M. Uchitelle*
|
1131
1044
|
|
1132
|
-
|
1045
|
+
* Deprecate `"primary"` as the `connection_specification_name` for `ActiveRecord::Base`.
|
1133
1046
|
|
1134
|
-
|
1135
|
-
class AnimalsModel < ApplicationRecord
|
1136
|
-
self.abstract_class = true
|
1047
|
+
`"primary"` has been deprecated as the `connection_specification_name` for `ActiveRecord::Base` in favor of using `"ActiveRecord::Base"`. This change affects calls to `ActiveRecord::Base.connection_handler.retrieve_connection` and `ActiveRecord::Base.connection_handler.remove_connection`. If you're calling these methods with `"primary"`, please switch to `"ActiveRecord::Base"`.
|
1137
1048
|
|
1138
|
-
|
1139
|
-
end
|
1049
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1140
1050
|
|
1141
|
-
|
1142
|
-
|
1143
|
-
end
|
1144
|
-
```
|
1051
|
+
* Add `ActiveRecord::Validations::NumericalityValidator` with
|
1052
|
+
support for casting floats using a database columns' precision value.
|
1145
1053
|
|
1146
|
-
|
1147
|
-
a database that the model didn't connect to. Connecting to the database in this block is
|
1148
|
-
useful when you have another defined connection, for example `slow_replica` that you don't
|
1149
|
-
want to connect to by default but need in the console, or a specific code block.
|
1054
|
+
*Gannon McGibbon*
|
1150
1055
|
|
1151
|
-
|
1152
|
-
ActiveRecord::
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
```
|
1056
|
+
* Enforce fresh ETag header after a collection's contents change by adding
|
1057
|
+
ActiveRecord::Relation#cache_key_with_version. This method will be used by
|
1058
|
+
ActionController::ConditionalGet to ensure that when collection cache versioning
|
1059
|
+
is enabled, requests using ConditionalGet don't return the same ETag header
|
1060
|
+
after a collection is modified.
|
1157
1061
|
|
1158
|
-
|
1159
|
-
ActiveRecord::Base.connected_to(database: :slow_replica) do
|
1160
|
-
SlowReplicaModel.first # if the db config has a slow_replica configuration this will be used to do the lookup, otherwise this will throw an exception
|
1161
|
-
end
|
1162
|
-
```
|
1062
|
+
Fixes #38078.
|
1163
1063
|
|
1164
|
-
*
|
1064
|
+
*Aaron Lipman*
|
1165
1065
|
|
1166
|
-
*
|
1066
|
+
* Skip test database when running `db:create` or `db:drop` in development
|
1067
|
+
with `DATABASE_URL` set.
|
1167
1068
|
|
1168
|
-
|
1169
|
-
commit checks that only valid definition values are provided, those can
|
1170
|
-
be a Hash, an array of Symbols or an array of Strings. Otherwise it
|
1171
|
-
raises an `ArgumentError`.
|
1069
|
+
*Brian Buchalter*
|
1172
1070
|
|
1173
|
-
|
1071
|
+
* Don't allow mutations on the database configurations hash.
|
1174
1072
|
|
1175
|
-
|
1073
|
+
Freeze the configurations hash to disallow directly changing it. If applications need to change the hash, for example to create databases for parallelization, they should use the `DatabaseConfig` object directly.
|
1176
1074
|
|
1177
|
-
|
1075
|
+
Before:
|
1178
1076
|
|
1077
|
+
```ruby
|
1078
|
+
@db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
|
1079
|
+
@db_config.configuration_hash.merge!(idle_timeout: "0.02")
|
1179
1080
|
```
|
1180
|
-
class Post < ActiveRecord::Base
|
1181
|
-
has_one :category
|
1182
|
-
belongs_to :author
|
1183
|
-
has_many :comments
|
1184
|
-
end
|
1185
1081
|
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1082
|
+
After:
|
1083
|
+
|
1084
|
+
```ruby
|
1085
|
+
@db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
|
1086
|
+
config = @db_config.configuration_hash.merge(idle_timeout: "0.02")
|
1087
|
+
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.spec_name, config)
|
1190
1088
|
```
|
1191
1089
|
|
1192
|
-
*
|
1090
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1193
1091
|
|
1194
|
-
*
|
1195
|
-
With this change you can create indexes while adding new
|
1196
|
-
columns into the existing tables.
|
1092
|
+
* Remove `:connection_id` from the `sql.active_record` notification.
|
1197
1093
|
|
1198
|
-
|
1094
|
+
*Aaron Patterson*, *Rafael Mendonça França*
|
1199
1095
|
|
1200
|
-
|
1201
|
-
t.string :country_code, index: true
|
1202
|
-
end
|
1096
|
+
* The `:name` key will no longer be returned as part of `DatabaseConfig#configuration_hash`. Please use `DatabaseConfig#owner_name` instead.
|
1203
1097
|
|
1204
|
-
*
|
1098
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1205
1099
|
|
1206
|
-
*
|
1100
|
+
* ActiveRecord's `belongs_to_required_by_default` flag can now be set per model.
|
1207
1101
|
|
1208
|
-
|
1209
|
-
|
1102
|
+
You can now opt-out/opt-in specific models from having their associations required
|
1103
|
+
by default.
|
1210
1104
|
|
1211
|
-
|
1105
|
+
This change is meant to ease the process of migrating all your models to have
|
1106
|
+
their association required.
|
1212
1107
|
|
1213
|
-
*
|
1108
|
+
*Edouard Chin*
|
1214
1109
|
|
1215
|
-
|
1110
|
+
* The `connection_config` method has been deprecated, please use `connection_db_config` instead which will return a `DatabaseConfigurations::DatabaseConfig` instead of a `Hash`.
|
1216
1111
|
|
1217
|
-
*
|
1112
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1218
1113
|
|
1219
|
-
|
1114
|
+
* Retain explicit selections on the base model after applying `includes` and `joins`.
|
1220
1115
|
|
1221
|
-
|
1116
|
+
Resolves #34889.
|
1222
1117
|
|
1223
|
-
|
1118
|
+
*Patrick Rebsch*
|
1224
1119
|
|
1225
|
-
|
1120
|
+
* The `database` kwarg is deprecated without replacement because it can't be used for sharding and creates an issue if it's used during a request. Applications that need to create new connections should use `connects_to` instead.
|
1226
1121
|
|
1227
|
-
*
|
1122
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1228
1123
|
|
1229
|
-
|
1124
|
+
* Allow attributes to be fetched from Arel node groupings.
|
1230
1125
|
|
1231
|
-
*
|
1126
|
+
*Jeff Emminger*, *Gannon McGibbon*
|
1232
1127
|
|
1233
|
-
|
1234
|
-
create_table :users do |t|
|
1235
|
-
t.string :email
|
1236
|
-
end
|
1128
|
+
* A database URL can now contain a querystring value that contains an equal sign. This is needed to support passing PostgreSQL `options`.
|
1237
1129
|
|
1238
|
-
|
1239
|
-
```
|
1130
|
+
*Joshua Flanagan*
|
1240
1131
|
|
1241
|
-
|
1132
|
+
* Calling methods like `establish_connection` with a `Hash` which is invalid (eg: no `adapter`) will now raise an error the same way as connections defined in `config/database.yml`.
|
1242
1133
|
|
1243
|
-
*
|
1134
|
+
*John Crepezzi*
|
1244
1135
|
|
1245
|
-
|
1136
|
+
* Specifying `implicit_order_column` now subsorts the records by primary key if available to ensure deterministic results.
|
1246
1137
|
|
1247
|
-
*
|
1138
|
+
*Paweł Urbanek*
|
1248
1139
|
|
1249
|
-
*
|
1140
|
+
* `where(attr => [])` now loads an empty result without making a query.
|
1250
1141
|
|
1251
|
-
*
|
1142
|
+
*John Hawthorn*
|
1252
1143
|
|
1253
|
-
*
|
1144
|
+
* Fixed the performance regression for `primary_keys` introduced MySQL 8.0.
|
1254
1145
|
|
1255
|
-
|
1256
|
-
The previous default 3-Byte encoding character set `utf8` is not enough to support them.
|
1146
|
+
*Hiroyuki Ishii*
|
1257
1147
|
|
1258
|
-
|
1148
|
+
* Add support for `belongs_to` to `has_many` inversing.
|
1259
1149
|
|
1260
|
-
*
|
1150
|
+
*Gannon McGibbon*
|
1261
1151
|
|
1262
|
-
|
1152
|
+
* Allow length configuration for `has_secure_token` method. The minimum length
|
1153
|
+
is set at 24 characters.
|
1263
1154
|
|
1264
|
-
|
1265
|
-
sensitive values of database columns when calling `#inspect`.
|
1266
|
-
We also added `ActiveRecord::Base::filter_attributes`/`=` in order to
|
1267
|
-
specify sensitive attributes to specific model.
|
1155
|
+
Before:
|
1268
1156
|
|
1157
|
+
```ruby
|
1158
|
+
has_secure_token :auth_token
|
1269
1159
|
```
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1160
|
+
|
1161
|
+
After:
|
1162
|
+
|
1163
|
+
```ruby
|
1164
|
+
has_secure_token :default_token # 24 characters
|
1165
|
+
has_secure_token :auth_token, length: 36 # 36 characters
|
1166
|
+
has_secure_token :invalid_token, length: 12 # => ActiveRecord::SecureToken::MinimumLengthError
|
1274
1167
|
```
|
1275
1168
|
|
1276
|
-
*
|
1169
|
+
*Bernardo de Araujo*
|
1277
1170
|
|
1278
|
-
* Deprecate `
|
1279
|
-
`indexes_per_table`, `columns_per_multicolumn_index`, `sql_query_length`,
|
1280
|
-
and `joins_per_query` methods in `DatabaseLimits`.
|
1171
|
+
* Deprecate `DatabaseConfigurations#to_h`. These connection hashes are still available via `ActiveRecord::Base.configurations.configs_for`.
|
1281
1172
|
|
1282
|
-
*
|
1173
|
+
*Eileen Uchitelle*, *John Crepezzi*
|
1283
1174
|
|
1284
|
-
* `
|
1175
|
+
* Add `DatabaseConfig#configuration_hash` to return database configuration hashes with symbol keys, and use all symbol-key configuration hashes internally. Deprecate `DatabaseConfig#config` which returns a String-keyed `Hash` with the same values.
|
1285
1176
|
|
1286
|
-
|
1287
|
-
is an inflexible data model. In order to improve multiple-database
|
1288
|
-
handling in Rails, we've changed this to return an object. Some methods
|
1289
|
-
are provided to make the object behave hash-like in order to ease the
|
1290
|
-
transition process. Since most applications don't manipulate the hash
|
1291
|
-
we've decided to add backwards-compatible functionality that will throw
|
1292
|
-
a deprecation warning if used, however calling `ActiveRecord::Base.configurations`
|
1293
|
-
will use the new version internally and externally.
|
1177
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
1294
1178
|
|
1295
|
-
|
1179
|
+
* Allow column names to be passed to `remove_index` positionally along with other options.
|
1296
1180
|
|
1297
|
-
|
1298
|
-
development:
|
1299
|
-
adapter: sqlite3
|
1300
|
-
database: db/development.sqlite3
|
1301
|
-
```
|
1181
|
+
Passing other options can be necessary to make `remove_index` correctly reversible.
|
1302
1182
|
|
1303
|
-
|
1183
|
+
Before:
|
1304
1184
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1185
|
+
add_index :reports, :report_id # => works
|
1186
|
+
add_index :reports, :report_id, unique: true # => works
|
1187
|
+
remove_index :reports, :report_id # => works
|
1188
|
+
remove_index :reports, :report_id, unique: true # => ArgumentError
|
1189
|
+
|
1190
|
+
After:
|
1308
1191
|
|
1309
|
-
|
1192
|
+
remove_index :reports, :report_id, unique: true # => works
|
1310
1193
|
|
1311
|
-
|
1312
|
-
#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
1313
|
-
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
1314
|
-
@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
|
1315
|
-
]
|
1316
|
-
```
|
1194
|
+
*Eugene Kenny*
|
1317
1195
|
|
1318
|
-
|
1319
|
-
calling hash methods on the `configurations` hash directly, a new method `configs_for` has
|
1320
|
-
been provided that allows you to select the correct configuration. `env_name` and
|
1321
|
-
`spec_name` arguments are optional. For example, these return an array of
|
1322
|
-
database config objects for the requested environment and a single database config object
|
1323
|
-
will be returned for the requested environment and specification name respectively.
|
1196
|
+
* Allow bulk `ALTER` statements to drop and recreate indexes with the same name.
|
1324
1197
|
|
1325
|
-
|
1326
|
-
ActiveRecord::Base.configurations.configs_for(env_name: "development")
|
1327
|
-
ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
|
1328
|
-
```
|
1198
|
+
*Eugene Kenny*
|
1329
1199
|
|
1330
|
-
|
1200
|
+
* `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
|
1331
1201
|
|
1332
|
-
*
|
1202
|
+
*Eugene Kenny*
|
1333
1203
|
|
1334
|
-
|
1335
|
-
production:
|
1336
|
-
adapter: postgresql
|
1337
|
-
advisory_locks: false
|
1338
|
-
```
|
1204
|
+
* Call `while_preventing_writes` directly from `connected_to`.
|
1339
1205
|
|
1340
|
-
|
1206
|
+
In some cases application authors want to use the database switching middleware and make explicit calls with `connected_to`. It's possible for an app to turn off writes and not turn them back on by the time we call `connected_to(role: :writing)`.
|
1341
1207
|
|
1342
|
-
|
1208
|
+
This change allows apps to fix this by assuming if a role is writing we want to allow writes, except in the case it's explicitly turned off.
|
1343
1209
|
|
1344
|
-
*
|
1210
|
+
*Eileen M. Uchitelle*
|
1345
1211
|
|
1346
|
-
*
|
1212
|
+
* Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter in the edge case when the query is terminated during filesort.
|
1347
1213
|
|
1348
|
-
|
1214
|
+
*Kir Shatrov*
|
1349
1215
|
|
1350
|
-
|
1216
|
+
* Stop trying to read yaml file fixtures when loading Active Record fixtures.
|
1351
1217
|
|
1352
|
-
*
|
1218
|
+
*Gannon McGibbon*
|
1353
1219
|
|
1354
|
-
*
|
1355
|
-
seed load in environments without Rails and custom DB configuration
|
1220
|
+
* Deprecate `.reorder(nil)` with `.first` / `.first!` taking non-deterministic result.
|
1356
1221
|
|
1357
|
-
|
1222
|
+
To continue taking non-deterministic result, use `.take` / `.take!` instead.
|
1358
1223
|
|
1359
|
-
*
|
1224
|
+
*Ryuta Kamizono*
|
1360
1225
|
|
1361
|
-
|
1226
|
+
* Preserve user supplied joins order as much as possible.
|
1362
1227
|
|
1363
|
-
|
1228
|
+
Fixes #36761, #34328, #24281, #12953.
|
1364
1229
|
|
1365
1230
|
*Ryuta Kamizono*
|
1366
1231
|
|
1367
|
-
*
|
1232
|
+
* Allow `matches_regex` and `does_not_match_regexp` on the MySQL Arel visitor.
|
1233
|
+
|
1234
|
+
*James Pearson*
|
1368
1235
|
|
1369
|
-
|
1236
|
+
* Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section.
|
1370
1237
|
|
1371
|
-
*
|
1238
|
+
*Tongfei Gao*
|
1239
|
+
|
1240
|
+
* Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
|
1372
1241
|
|
1373
|
-
*
|
1242
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
1374
1243
|
|
1375
|
-
|
1244
|
+
* Add a warning for enum elements with 'not_' prefix.
|
1376
1245
|
|
1377
|
-
|
1246
|
+
class Foo
|
1247
|
+
enum status: [:sent, :not_sent]
|
1248
|
+
end
|
1378
1249
|
|
1379
|
-
|
1250
|
+
*Edu Depetris*
|
1380
1251
|
|
1381
|
-
|
1252
|
+
* Make currency symbols optional for money column type in PostgreSQL.
|
1382
1253
|
|
1383
|
-
*
|
1254
|
+
*Joel Schneider*
|
1384
1255
|
|
1385
|
-
|
1256
|
+
* Add support for beginless ranges, introduced in Ruby 2.7.
|
1386
1257
|
|
1387
|
-
*
|
1388
|
-
use loaded association ids if present.
|
1258
|
+
*Josh Goodall*
|
1389
1259
|
|
1390
|
-
|
1260
|
+
* Add `database_exists?` method to connection adapters to check if a database exists.
|
1391
1261
|
|
1392
|
-
*
|
1262
|
+
*Guilherme Mansur*
|
1393
1263
|
|
1394
|
-
|
1264
|
+
* Loading the schema for a model that has no `table_name` raises a `TableNotSpecified` error.
|
1395
1265
|
|
1396
|
-
*
|
1266
|
+
*Guilherme Mansur*, *Eugene Kenny*
|
1397
1267
|
|
1398
|
-
|
1268
|
+
* PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
|
1399
1269
|
|
1400
|
-
|
1270
|
+
Fixes #36022.
|
1271
|
+
|
1272
|
+
*Ryuta Kamizono*
|
1273
|
+
|
1274
|
+
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
1401
1275
|
|
1402
|
-
|
1276
|
+
Fixes #36465.
|
1403
1277
|
|
1404
|
-
*
|
1278
|
+
*Jeff Doering*
|
1405
1279
|
|
1406
|
-
|
1280
|
+
* Add support for multiple databases to `rails db:abort_if_pending_migrations`.
|
1407
1281
|
|
1408
|
-
*
|
1282
|
+
*Mark Lee*
|
1409
1283
|
|
1410
|
-
|
1284
|
+
* Fix sqlite3 collation parsing when using decimal columns.
|
1411
1285
|
|
1412
|
-
*
|
1286
|
+
*Martin R. Schuster*
|
1413
1287
|
|
1414
|
-
|
1288
|
+
* Fix invalid schema when primary key column has a comment.
|
1415
1289
|
|
1416
|
-
|
1290
|
+
Fixes #29966.
|
1417
1291
|
|
1418
|
-
*
|
1292
|
+
*Guilherme Goettems Schneider*
|
1419
1293
|
|
1420
|
-
*
|
1421
|
-
`ActiveRecord::Base.find_or_create_by`/`!` by leaning on unique constraints in the database.
|
1294
|
+
* Fix table comment also being applied to the primary key column.
|
1422
1295
|
|
1423
|
-
*
|
1296
|
+
*Guilherme Goettems Schneider*
|
1424
1297
|
|
1425
|
-
*
|
1298
|
+
* Allow generated `create_table` migrations to include or skip timestamps.
|
1426
1299
|
|
1427
|
-
*
|
1300
|
+
*Michael Duchemin*
|
1428
1301
|
|
1429
1302
|
|
1430
|
-
Please check [
|
1303
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
|