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