activerecord 6.0.0 → 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 +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -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 -3
- 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 +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- 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.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- 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 +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- 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/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- 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 +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- 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 +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- 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 +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- 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 +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- 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 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- 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 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- 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 +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- 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/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- 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.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- 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 +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -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.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- 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.rb +3 -1
- 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/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +6 -2
- 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 +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- 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 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 418812373f3ff5fd16133fe0928b94b80b78b8a366abfc23a205fcb2ccc5a3e3
|
4
|
+
data.tar.gz: 70db1902a8fc82b1c46f8a7731ffb358357bc8cac29564a57881a732dbd2a65a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31ae64f629cb62f63bc37c74a888d557f9f0b102d401f2f9cf62c7d31655d99e5161ae9bc7f8be874c7a9cf27ec879dde3c04075df5cb2b5868891c0db144a50
|
7
|
+
data.tar.gz: cfc9585f3a6f53187707a9d96503269e3d4b1c5f1fe8c5f4db3bdefe8ce636042b6cf1fe9fb233491d1e8197f52293a7018a2f9925f1e34644ad1e30b134d59f
|
data/CHANGELOG.md
CHANGED
@@ -1,1013 +1,1303 @@
|
|
1
|
-
## Rails 6.
|
1
|
+
## Rails 6.1.0 (December 09, 2020) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
4
4
|
|
5
|
-
Fixes #
|
5
|
+
Fixes #39065.
|
6
6
|
|
7
|
-
*
|
7
|
+
*Alex Ghiculescu*
|
8
8
|
|
9
|
-
*
|
9
|
+
* Change `attribute_for_inspect` to take `filter_attributes` in consideration.
|
10
10
|
|
11
|
-
*
|
11
|
+
*Rafael Mendonça França*
|
12
12
|
|
13
|
-
*
|
13
|
+
* Fix odd behavior of inverse_of with multiple belongs_to to same class.
|
14
14
|
|
15
|
-
|
16
|
-
enum status: [:sent, :not_sent]
|
17
|
-
end
|
15
|
+
Fixes #35204.
|
18
16
|
|
19
|
-
*
|
17
|
+
*Tomoyuki Kai*
|
20
18
|
|
21
|
-
*
|
19
|
+
* Build predicate conditions with objects that delegate `#id` and primary key:
|
22
20
|
|
23
|
-
|
21
|
+
```ruby
|
22
|
+
class AdminAuthor
|
23
|
+
delegate_missing_to :@author
|
24
24
|
|
25
|
+
def initialize(author)
|
26
|
+
@author = author
|
27
|
+
end
|
28
|
+
end
|
25
29
|
|
26
|
-
|
30
|
+
Post.where(author: AdminAuthor.new(author))
|
31
|
+
```
|
27
32
|
|
28
|
-
*
|
33
|
+
*Sean Doyle*
|
29
34
|
|
30
|
-
|
35
|
+
* Add `connected_to_many` API.
|
31
36
|
|
32
|
-
|
37
|
+
This API allows applications to connect to multiple databases at once without switching all of them or implementing a deeply nested stack.
|
33
38
|
|
34
|
-
|
39
|
+
Before:
|
35
40
|
|
36
|
-
|
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
|
37
48
|
|
38
|
-
|
49
|
+
After:
|
39
50
|
|
40
|
-
|
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
|
41
56
|
|
42
|
-
*
|
57
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
43
58
|
|
44
|
-
*
|
59
|
+
* Add option to raise or log for `ActiveRecord::StrictLoadingViolationError`.
|
45
60
|
|
46
|
-
|
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.
|
47
62
|
|
48
|
-
|
63
|
+
Set `config.active_record.action_on_strict_loading_violation` to `:log` errors instead of raising.
|
49
64
|
|
50
|
-
|
65
|
+
*Eileen M. Uchitelle*
|
51
66
|
|
52
|
-
|
67
|
+
* Allow the inverse of a `has_one` association that was previously autosaved to be loaded.
|
53
68
|
|
54
|
-
|
69
|
+
Fixes #34255.
|
55
70
|
|
56
|
-
*
|
71
|
+
*Steven Weber*
|
72
|
+
|
73
|
+
* Optimise the length of index names for polymorphic references by using the reference name rather than the type and id column names.
|
74
|
+
|
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.
|
76
|
+
|
77
|
+
This change reduces the chance of that happening by using the reference name, e.g. `index_my_table_on_my_reference`.
|
57
78
|
|
58
|
-
|
79
|
+
Fixes #38655.
|
59
80
|
|
60
|
-
|
81
|
+
*Luke Redpath*
|
82
|
+
|
83
|
+
* MySQL: Uniqueness validator now respects default database collation,
|
84
|
+
no longer enforce case sensitive comparison by default.
|
61
85
|
|
62
86
|
*Ryuta Kamizono*
|
63
87
|
|
88
|
+
* Remove deprecated methods from `ActiveRecord::ConnectionAdapters::DatabaseLimits`.
|
89
|
+
|
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`
|
64
97
|
|
65
|
-
|
98
|
+
*Rafael Mendonça França*
|
66
99
|
|
67
|
-
*
|
100
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_multi_insert?`.
|
68
101
|
|
69
|
-
*
|
102
|
+
*Rafael Mendonça França*
|
70
103
|
|
71
|
-
*
|
104
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_foreign_keys_in_create?`.
|
72
105
|
|
73
|
-
|
74
|
-
all = [treasures(:diamond), treasures(:sapphire), cars(:honda), treasures(:sapphire)]
|
75
|
-
assert_equal all, PriceEstimate.all.map(&:estimate_of)
|
76
|
-
```
|
106
|
+
*Rafael Mendonça França*
|
77
107
|
|
78
|
-
|
108
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#supports_ranges?`.
|
79
109
|
|
80
|
-
|
81
|
-
sapphire = treasures(:sapphire)
|
110
|
+
*Rafael Mendonça França*
|
82
111
|
|
83
|
-
|
84
|
-
e.estimate_of_type == sapphire.class.polymorphic_name
|
85
|
-
}.reject { |e|
|
86
|
-
e.estimate_of_id == sapphire.id
|
87
|
-
}
|
88
|
-
assert_equal [cars(:honda)], nor
|
112
|
+
* Remove deprecated `ActiveRecord::Base#update_attributes` and `ActiveRecord::Base#update_attributes!`.
|
89
113
|
|
90
|
-
|
91
|
-
estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
|
92
|
-
)
|
93
|
-
assert_equal nor, without_sapphire.map(&:estimate_of)
|
94
|
-
```
|
114
|
+
*Rafael Mendonça França*
|
95
115
|
|
96
|
-
|
116
|
+
* Remove deprecated `migrations_path` argument in `ActiveRecord::ConnectionAdapter::SchemaStatements#assume_migrated_upto_version`.
|
97
117
|
|
98
|
-
|
99
|
-
sapphire = treasures(:sapphire)
|
118
|
+
*Rafael Mendonça França*
|
100
119
|
|
101
|
-
|
102
|
-
assert_equal [treasures(:diamond), cars(:honda)], nand
|
120
|
+
* Remove deprecated `config.active_record.sqlite3.represent_boolean_as_integer`.
|
103
121
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
122
|
+
*Rafael Mendonça França*
|
123
|
+
|
124
|
+
* `relation.create` does no longer leak scope to class level querying methods
|
125
|
+
in initialization block and callbacks.
|
126
|
+
|
127
|
+
Before:
|
128
|
+
|
129
|
+
User.where(name: "John").create do |john|
|
130
|
+
User.find_by(name: "David") # => nil
|
131
|
+
end
|
132
|
+
|
133
|
+
After:
|
134
|
+
|
135
|
+
User.where(name: "John").create do |john|
|
136
|
+
User.find_by(name: "David") # => #<User name: "David", ...>
|
137
|
+
end
|
109
138
|
|
110
139
|
*Ryuta Kamizono*
|
111
140
|
|
112
|
-
*
|
141
|
+
* Named scope chain does no longer leak scope to class level querying methods.
|
142
|
+
|
143
|
+
class User < ActiveRecord::Base
|
144
|
+
scope :david, -> { User.where(name: "David") }
|
145
|
+
end
|
146
|
+
|
147
|
+
Before:
|
113
148
|
|
114
|
-
|
149
|
+
User.where(name: "John").david
|
150
|
+
# SELECT * FROM users WHERE name = 'John' AND name = 'David'
|
151
|
+
|
152
|
+
After:
|
153
|
+
|
154
|
+
User.where(name: "John").david
|
155
|
+
# SELECT * FROM users WHERE name = 'David'
|
115
156
|
|
116
157
|
*Ryuta Kamizono*
|
117
158
|
|
118
|
-
*
|
119
|
-
the versioned entries in `ActiveSupport::Cache`. This also means that
|
120
|
-
`ActiveRecord::Relation#cache_key` will now return a stable key that does not
|
121
|
-
include the max timestamp or count any more.
|
159
|
+
* Remove deprecated methods from `ActiveRecord::DatabaseConfigurations`.
|
122
160
|
|
123
|
-
|
124
|
-
|
125
|
-
|
161
|
+
`fetch`
|
162
|
+
`each`
|
163
|
+
`first`
|
164
|
+
`values`
|
165
|
+
`[]=`
|
126
166
|
|
127
|
-
*
|
167
|
+
*Rafael Mendonça França*
|
128
168
|
|
129
|
-
*
|
169
|
+
* `where.not` now generates NAND predicates instead of NOR.
|
130
170
|
|
131
|
-
|
171
|
+
Before:
|
132
172
|
|
133
|
-
|
173
|
+
User.where.not(name: "Jon", role: "admin")
|
174
|
+
# SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
|
134
175
|
|
135
|
-
|
136
|
-
`to` and `from` options are specified.
|
176
|
+
After:
|
137
177
|
|
138
|
-
|
178
|
+
User.where.not(name: "Jon", role: "admin")
|
179
|
+
# SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
|
139
180
|
|
140
|
-
*
|
181
|
+
*Rafael Mendonça França*
|
141
182
|
|
142
|
-
|
183
|
+
* Remove deprecated `ActiveRecord::Result#to_hash` method.
|
143
184
|
|
144
|
-
*
|
185
|
+
*Rafael Mendonça França*
|
145
186
|
|
146
|
-
*
|
187
|
+
* Deprecate `ActiveRecord::Base.allow_unsafe_raw_sql`.
|
147
188
|
|
148
|
-
|
149
|
-
associations, the callback for a `has_many` association was run while
|
150
|
-
another instance of the same callback on the same association hadn't
|
151
|
-
finished running. When control returned to the first instance of the
|
152
|
-
callback, the instance variable had changed, and subsequent associated
|
153
|
-
records weren't saved correctly. Specifically, the ID field for the
|
154
|
-
`belongs_to` corresponding to the `has_many` was `nil`.
|
189
|
+
*Rafael Mendonça França*
|
155
190
|
|
156
|
-
|
191
|
+
* Remove deprecated support for using unsafe raw SQL in `ActiveRecord::Relation` methods.
|
157
192
|
|
158
|
-
*
|
193
|
+
*Rafael Mendonça França*
|
159
194
|
|
160
|
-
*
|
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`.
|
161
197
|
|
162
|
-
|
198
|
+
*Omri Gabay*
|
199
|
+
|
200
|
+
* Connections can be granularly switched for abstract classes when `connected_to` is called.
|
201
|
+
|
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.
|
203
|
+
|
204
|
+
Example usage:
|
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`.
|
163
207
|
|
164
208
|
```ruby
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
209
|
+
ActiveRecord::Base.connected_to(role: :reading) do
|
210
|
+
User.first # reads from default replica
|
211
|
+
Dog.first # reads from default replica
|
212
|
+
|
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
|
217
|
+
|
218
|
+
User.first # reads from default replica
|
219
|
+
Dog.first # reads from default replica
|
220
|
+
|
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
|
169
226
|
```
|
170
227
|
|
171
|
-
|
228
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
229
|
+
|
230
|
+
* Allow double-dash comment syntax when querying read-only databases
|
231
|
+
|
232
|
+
*James Adam*
|
233
|
+
|
234
|
+
* Add `values_at` method.
|
235
|
+
|
236
|
+
Returns an array containing the values associated with the given methods.
|
172
237
|
|
173
238
|
```ruby
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
|
239
|
+
topic = Topic.first
|
240
|
+
topic.values_at(:title, :author_name)
|
241
|
+
# => ["Budget", "Jason"]
|
178
242
|
```
|
179
243
|
|
180
|
-
|
244
|
+
Similar to `Hash#values_at` but on an Active Record instance.
|
181
245
|
|
182
|
-
*
|
183
|
-
whether preloaded / eager loaded or not, with the exception of `unscoped`.
|
246
|
+
*Guillaume Briday*
|
184
247
|
|
185
|
-
|
248
|
+
* Fix `read_attribute_before_type_cast` to consider attribute aliases.
|
249
|
+
|
250
|
+
*Marcelo Lauxen*
|
251
|
+
|
252
|
+
* Support passing record to uniqueness validator `:conditions` callable:
|
186
253
|
|
187
254
|
```ruby
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
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
|
+
}
|
192
260
|
end
|
193
261
|
```
|
194
262
|
|
195
|
-
|
263
|
+
*Eliot Sykes*
|
264
|
+
|
265
|
+
* `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
|
266
|
+
total number of rows affected, just like their non-batched counterparts.
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
Person.in_batches.update_all("first_name = 'Eugene'") # => 42
|
270
|
+
Person.in_batches.delete_all # => 42
|
271
|
+
```
|
272
|
+
|
273
|
+
Fixes #40287.
|
274
|
+
|
275
|
+
*Eugene Kenny*
|
276
|
+
|
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.
|
282
|
+
|
283
|
+
To use this in 6.1, you need to place the next string to your model file:
|
284
|
+
|
285
|
+
attribute :duration, :interval
|
286
|
+
|
287
|
+
To keep old behavior until 6.2 is released:
|
288
|
+
|
289
|
+
attribute :duration, :string
|
290
|
+
|
291
|
+
Example:
|
292
|
+
|
293
|
+
create_table :events do |t|
|
294
|
+
t.string :name
|
295
|
+
t.interval :duration
|
296
|
+
end
|
297
|
+
|
298
|
+
class Event < ApplicationRecord
|
299
|
+
attribute :duration, :interval
|
300
|
+
end
|
301
|
+
|
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
|
307
|
+
|
308
|
+
*Andrey Novikov*
|
309
|
+
|
310
|
+
* Allow associations supporting the `dependent:` key to take `dependent: :destroy_async`.
|
196
311
|
|
197
312
|
```ruby
|
198
|
-
|
199
|
-
|
200
|
-
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
201
|
-
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
313
|
+
class Account < ActiveRecord::Base
|
314
|
+
belongs_to :supplier, dependent: :destroy_async
|
202
315
|
end
|
203
316
|
```
|
204
317
|
|
205
|
-
|
318
|
+
`:destroy_async` will enqueue a job to destroy associated records in the background.
|
206
319
|
|
207
|
-
*
|
320
|
+
*DHH*, *George Claghorn*, *Cory Gwin*, *Rafael Mendonça França*, *Adrianna Chang*
|
208
321
|
|
209
|
-
* Add `rails db:
|
322
|
+
* Add `SKIP_TEST_DATABASE` environment variable to disable modifying the test database when `rails db:create` and `rails db:drop` are called.
|
210
323
|
|
211
|
-
|
324
|
+
*Jason Schweier*
|
212
325
|
|
213
|
-
|
326
|
+
* `connects_to` can only be called on `ActiveRecord::Base` or abstract classes.
|
214
327
|
|
215
|
-
|
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.
|
216
329
|
|
217
|
-
*
|
330
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
331
|
+
|
332
|
+
* All connection adapters `execute` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
333
|
+
`ActiveRecord::StatementInvalid` when they encounter a connection error.
|
218
334
|
|
219
|
-
*
|
220
|
-
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
335
|
+
*Jean Boussier*
|
221
336
|
|
222
|
-
|
337
|
+
* `Mysql2Adapter#quote_string` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
338
|
+
`ActiveRecord::StatementInvalid` when it can't connect to the MySQL server.
|
223
339
|
|
224
|
-
*
|
340
|
+
*Jean Boussier*
|
341
|
+
|
342
|
+
* Add support for check constraints that are `NOT VALID` via `validate: false` (PostgreSQL-only).
|
343
|
+
|
344
|
+
*Alex Robbin*
|
345
|
+
|
346
|
+
* Ensure the default configuration is considered primary or first for an environment
|
347
|
+
|
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.
|
349
|
+
|
350
|
+
*Eileen M. Uchitelle*
|
225
351
|
|
226
|
-
*
|
352
|
+
* Allow `where` references association names as joined table name aliases.
|
227
353
|
|
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
|
359
|
+
|
360
|
+
# ... FROM comments LEFT OUTER JOIN comments children ON ... WHERE children.label = 1
|
361
|
+
Comment.includes(:children).where("children.label": "child")
|
228
362
|
```
|
229
|
-
|
230
|
-
|
363
|
+
|
364
|
+
*Ryuta Kamizono*
|
365
|
+
|
366
|
+
* Support storing demodulized class name for polymorphic type.
|
367
|
+
|
368
|
+
Before Rails 6.1, storing demodulized class name is supported only for STI type
|
369
|
+
by `store_full_sti_class` class attribute.
|
370
|
+
|
371
|
+
Now `store_full_class_name` class attribute can handle both STI and polymorphic types.
|
372
|
+
|
373
|
+
*Ryuta Kamizono*
|
374
|
+
|
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.
|
378
|
+
|
379
|
+
*fatkodima*
|
380
|
+
|
381
|
+
* Respect the `select` values for eager loading.
|
382
|
+
|
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
|
231
397
|
```
|
232
398
|
|
233
|
-
*
|
399
|
+
*Ryuta Kamizono*
|
234
400
|
|
235
|
-
*
|
401
|
+
* Allow attribute's default to be configured but keeping its own type.
|
236
402
|
|
237
|
-
|
403
|
+
```ruby
|
404
|
+
class Post < ActiveRecord::Base
|
405
|
+
attribute :written_at, default: -> { Time.now.utc }
|
406
|
+
end
|
407
|
+
|
408
|
+
# Rails 6.0
|
409
|
+
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
|
238
410
|
|
411
|
+
# Rails 6.1
|
412
|
+
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
|
239
413
|
```
|
240
|
-
|
241
|
-
|
414
|
+
|
415
|
+
*Ryuta Kamizono*
|
416
|
+
|
417
|
+
* Allow default to be configured for Enum.
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
class Book < ActiveRecord::Base
|
421
|
+
enum status: [:proposed, :written, :published], _default: :published
|
422
|
+
end
|
423
|
+
|
424
|
+
Book.new.status # => "published"
|
242
425
|
```
|
243
426
|
|
244
|
-
|
427
|
+
*Ryuta Kamizono*
|
245
428
|
|
246
|
-
|
429
|
+
* Deprecate YAML loading from legacy format older than Rails 5.0.
|
247
430
|
|
248
|
-
*
|
431
|
+
*Ryuta Kamizono*
|
249
432
|
|
250
|
-
|
251
|
-
|
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.
|
252
437
|
|
253
|
-
|
438
|
+
*Sean Griffin*, *Ryuta Kamizono*
|
254
439
|
|
255
|
-
|
256
|
-
# SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
|
440
|
+
* Deprecate `map!` and `collect!` on `ActiveRecord::Result`.
|
257
441
|
|
258
|
-
|
442
|
+
*Ryuta Kamizono*
|
259
443
|
|
260
|
-
|
261
|
-
# SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
444
|
+
* Support `relation.and` for intersection as Set theory.
|
262
445
|
|
263
|
-
|
446
|
+
```ruby
|
447
|
+
david_and_mary = Author.where(id: [david, mary])
|
448
|
+
mary_and_bob = Author.where(id: [mary, bob])
|
449
|
+
|
450
|
+
david_and_mary.merge(mary_and_bob) # => [mary, bob]
|
264
451
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
* https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-2017
|
269
|
-
* https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.admin.perf.doc/doc/c0070117.html
|
452
|
+
david_and_mary.and(mary_and_bob) # => [mary]
|
453
|
+
david_and_mary.or(mary_and_bob) # => [david, mary, bob]
|
454
|
+
```
|
270
455
|
|
271
456
|
*Ryuta Kamizono*
|
272
457
|
|
273
|
-
*
|
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)`.
|
461
|
+
|
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]
|
465
|
+
|
466
|
+
# Rails 6.1 (both conflict conditions exists, deprecated)
|
467
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
|
274
468
|
|
275
|
-
|
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]
|
276
471
|
|
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]
|
277
475
|
```
|
278
|
-
|
279
|
-
|
476
|
+
|
477
|
+
*Ryuta Kamizono*
|
478
|
+
|
479
|
+
* Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case.
|
480
|
+
|
481
|
+
*Peter Fry*
|
482
|
+
|
483
|
+
* Resolve issue with insert_all unique_by option when used with expression index.
|
484
|
+
|
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.
|
488
|
+
|
489
|
+
Usage:
|
490
|
+
|
491
|
+
```ruby
|
492
|
+
create_table :books, id: :integer, force: true do |t|
|
493
|
+
t.column :name, :string
|
494
|
+
t.index "lower(name)", unique: true
|
280
495
|
end
|
281
496
|
|
282
|
-
|
497
|
+
Book.insert_all [{ name: "MyTest" }], unique_by: :index_books_on_lower_name
|
283
498
|
```
|
284
499
|
|
285
|
-
|
500
|
+
Fixes #39516.
|
286
501
|
|
287
|
-
*
|
502
|
+
*Austen Madden*
|
288
503
|
|
289
|
-
|
504
|
+
* Add basic support for CHECK constraints to database migrations.
|
290
505
|
|
291
|
-
|
292
|
-
allowing bulk inserts akin to the bulk updates provided by `update_all` and
|
293
|
-
bulk deletes by `delete_all`.
|
506
|
+
Usage:
|
294
507
|
|
295
|
-
|
296
|
-
|
297
|
-
|
508
|
+
```ruby
|
509
|
+
add_check_constraint :products, "price > 0", name: "price_check"
|
510
|
+
remove_check_constraint :products, name: "price_check"
|
511
|
+
```
|
298
512
|
|
299
|
-
*
|
513
|
+
*fatkodima*
|
300
514
|
|
301
|
-
* Add `
|
302
|
-
for
|
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.
|
303
518
|
|
304
|
-
|
519
|
+
Usage:
|
305
520
|
|
306
|
-
|
521
|
+
```ruby
|
522
|
+
class Developer < ApplicationRecord
|
523
|
+
self.strict_loading_by_default = true
|
307
524
|
|
308
|
-
|
525
|
+
has_many :projects
|
526
|
+
end
|
309
527
|
|
310
|
-
|
528
|
+
dev = Developer.first
|
529
|
+
dev.projects.first
|
530
|
+
# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
|
531
|
+
```
|
311
532
|
|
312
|
-
|
313
|
-
|
314
|
-
|
533
|
+
*bogdanvlviv*
|
534
|
+
|
535
|
+
* Deprecate passing an Active Record object to `quote`/`type_cast` directly.
|
315
536
|
|
316
537
|
*Ryuta Kamizono*
|
317
538
|
|
318
|
-
*
|
539
|
+
* Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic.
|
319
540
|
|
320
|
-
|
541
|
+
Before:
|
321
542
|
|
322
|
-
|
543
|
+
```ruby
|
544
|
+
create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
545
|
+
end
|
546
|
+
```
|
323
547
|
|
324
|
-
|
548
|
+
After:
|
325
549
|
|
326
|
-
|
550
|
+
```ruby
|
551
|
+
create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
552
|
+
end
|
553
|
+
```
|
327
554
|
|
328
|
-
|
329
|
-
enum status: %i[ drafted active trashed ]
|
330
|
-
end
|
555
|
+
*Ryuta Kamizono*
|
331
556
|
|
332
|
-
|
333
|
-
|
334
|
-
Post.not_trashed # => where.not(status: :trashed)
|
557
|
+
* Added delegated type as an alternative to single-table inheritance for representing class hierarchies.
|
558
|
+
See ActiveRecord::DelegatedType for the full description.
|
335
559
|
|
336
560
|
*DHH*
|
337
561
|
|
338
|
-
*
|
562
|
+
* Deprecate aggregations with group by duplicated fields.
|
339
563
|
|
340
|
-
|
564
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:group)` to deduplicate group fields.
|
341
565
|
|
342
|
-
|
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
|
+
# }
|
582
|
+
```
|
343
583
|
|
584
|
+
*Ryuta Kamizono*
|
344
585
|
|
345
|
-
|
586
|
+
* Deprecate duplicated query annotations.
|
346
587
|
|
347
|
-
|
588
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:annotate)` to deduplicate query annotations.
|
348
589
|
|
590
|
+
```ruby
|
591
|
+
accounts = Account.where(id: [1, 2]).annotate("david and mary")
|
349
592
|
|
350
|
-
|
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 */
|
351
596
|
|
352
|
-
|
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
|
+
```
|
353
601
|
|
354
602
|
*Ryuta Kamizono*
|
355
603
|
|
356
|
-
*
|
604
|
+
* Resolve conflict between counter cache and optimistic locking.
|
357
605
|
|
358
|
-
|
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.
|
359
610
|
|
360
|
-
|
611
|
+
Fixes #16449.
|
361
612
|
|
362
|
-
*
|
613
|
+
*Aaron Lipman*
|
363
614
|
|
364
|
-
*
|
615
|
+
* Support merging option `:rewhere` to allow mergee side condition to be replaced exactly.
|
365
616
|
|
366
|
-
|
367
|
-
|
617
|
+
```ruby
|
618
|
+
david_and_mary = Author.where(id: david.id..mary.id)
|
368
619
|
|
369
|
-
|
620
|
+
# both conflict conditions exists
|
621
|
+
david_and_mary.merge(Author.where(id: bob)) # => []
|
370
622
|
|
371
|
-
|
372
|
-
|
623
|
+
# mergee side condition is replaced by rewhere
|
624
|
+
david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
|
373
625
|
|
374
|
-
|
375
|
-
|
626
|
+
# mergee side condition is replaced by rewhere option
|
627
|
+
david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
|
628
|
+
```
|
376
629
|
|
377
|
-
|
378
|
-
`delete_all` on the matched records.
|
630
|
+
*Ryuta Kamizono*
|
379
631
|
|
380
|
-
|
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.
|
381
636
|
|
382
|
-
|
383
|
-
|
637
|
+
```ruby
|
638
|
+
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
|
384
639
|
|
385
|
-
|
386
|
-
david.posts.delete_by(id: [1, 2, 3])
|
640
|
+
User.find_signed signed_id # => nil, since the purpose does not match
|
387
641
|
|
388
|
-
|
642
|
+
travel 16.minutes
|
643
|
+
User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
|
389
644
|
|
390
|
-
|
645
|
+
travel_back
|
646
|
+
User.find_signed signed_id, purpose: :password_reset # => User.first
|
391
647
|
|
392
|
-
|
648
|
+
User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
|
649
|
+
```
|
393
650
|
|
394
|
-
*
|
651
|
+
*DHH*
|
395
652
|
|
396
|
-
*
|
653
|
+
* Support `ALGORITHM = INSTANT` DDL option for index operations on MySQL.
|
397
654
|
|
398
655
|
*Ryuta Kamizono*
|
399
656
|
|
400
|
-
*
|
401
|
-
regarded as leaked. Use `klass.unscoped` to avoid the leaking scope.
|
657
|
+
* Fix index creation to preserve index comment in bulk change table on MySQL.
|
402
658
|
|
403
659
|
*Ryuta Kamizono*
|
404
660
|
|
405
|
-
* Allow
|
661
|
+
* Allow `unscope` to be aware of table name qualified values.
|
406
662
|
|
407
|
-
|
408
|
-
application to automatically switch between the writing and reading
|
409
|
-
database connections.
|
663
|
+
It is possible to unscope only the column in the specified table.
|
410
664
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
an argument for a Resolver class and an Operations class where you are able
|
415
|
-
to change how the auto-switcher works to be most beneficial for your
|
416
|
-
application.
|
665
|
+
```ruby
|
666
|
+
posts = Post.joins(:comments).group(:"posts.hidden")
|
667
|
+
posts = posts.where("posts.hidden": false, "comments.hidden": false)
|
417
668
|
|
418
|
-
|
419
|
-
|
669
|
+
posts.count
|
670
|
+
# => { false => 10 }
|
420
671
|
|
672
|
+
# unscope both hidden columns
|
673
|
+
posts.unscope(where: :hidden).count
|
674
|
+
# => { false => 11, true => 1 }
|
675
|
+
|
676
|
+
# unscope only comments.hidden column
|
677
|
+
posts.unscope(where: :"comments.hidden").count
|
678
|
+
# => { false => 11 }
|
421
679
|
```
|
422
|
-
config.active_record.database_selector = { delay: 2.seconds }
|
423
|
-
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
|
424
|
-
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
|
425
|
-
```
|
426
680
|
|
427
|
-
|
428
|
-
|
681
|
+
*Ryuta Kamizono*, *Slava Korolev*
|
682
|
+
|
683
|
+
* Fix `rewhere` to truly overwrite collided where clause by new where clause.
|
684
|
+
|
685
|
+
```ruby
|
686
|
+
steve = Person.find_by(name: "Steve")
|
687
|
+
david = Author.find_by(name: "David")
|
688
|
+
|
689
|
+
relation = Essay.where(writer: steve)
|
429
690
|
|
691
|
+
# Before
|
692
|
+
relation.rewhere(writer: david).to_a # => []
|
693
|
+
|
694
|
+
# After
|
695
|
+
relation.rewhere(writer: david).to_a # => [david]
|
430
696
|
```
|
431
|
-
|
432
|
-
|
433
|
-
|
697
|
+
|
698
|
+
*Ryuta Kamizono*
|
699
|
+
|
700
|
+
* Inspect time attributes with subsec and time zone offset.
|
701
|
+
|
702
|
+
```ruby
|
703
|
+
p Knot.create
|
704
|
+
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000 +0000">
|
434
705
|
```
|
435
706
|
|
436
|
-
*
|
707
|
+
*akinomaeni*, *Jonathan Hefner*
|
437
708
|
|
438
|
-
*
|
709
|
+
* Deprecate passing a column to `type_cast`.
|
439
710
|
|
440
711
|
*Ryuta Kamizono*
|
441
712
|
|
442
|
-
*
|
713
|
+
* Deprecate `in_clause_length` and `allowed_index_name_length` in `DatabaseLimits`.
|
443
714
|
|
444
715
|
*Ryuta Kamizono*
|
445
716
|
|
717
|
+
* Support bulk insert/upsert on relation to preserve scope values.
|
446
718
|
|
447
|
-
|
719
|
+
*Josef Šimánek*, *Ryuta Kamizono*
|
448
720
|
|
449
|
-
*
|
721
|
+
* Preserve column comment value on changing column name on MySQL.
|
450
722
|
|
451
|
-
*
|
723
|
+
*Islam Taha*
|
452
724
|
|
453
|
-
*
|
725
|
+
* Add support for `if_exists` option for removing an index.
|
454
726
|
|
455
|
-
|
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.
|
456
728
|
|
457
|
-
*
|
729
|
+
*Eileen M. Uchitelle*
|
458
730
|
|
459
|
-
|
731
|
+
* Remove ibm_db, informix, mssql, oracle, and oracle12 Arel visitors which are not used in the code base.
|
460
732
|
|
461
|
-
*
|
733
|
+
*Ryuta Kamizono*
|
462
734
|
|
463
|
-
|
735
|
+
* Prevent `build_association` from `touching` a parent record if the record isn't persisted for `has_one` associations.
|
464
736
|
|
465
|
-
|
737
|
+
Fixes #38219.
|
466
738
|
|
467
|
-
*
|
739
|
+
*Josh Brody*
|
468
740
|
|
469
|
-
*
|
741
|
+
* Add support for `if_not_exists` option for adding index.
|
470
742
|
|
471
|
-
|
743
|
+
The `add_index` method respects `if_not_exists` option. If it is set to true
|
744
|
+
index won't be added.
|
472
745
|
|
473
|
-
|
746
|
+
Usage:
|
474
747
|
|
475
|
-
|
748
|
+
```ruby
|
749
|
+
add_index :users, :account_id, if_not_exists: true
|
750
|
+
```
|
476
751
|
|
477
|
-
|
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.
|
478
755
|
|
479
|
-
*
|
756
|
+
*Prathamesh Sonpatki*
|
480
757
|
|
481
|
-
*
|
758
|
+
* Add `ActiveRecord::Base#previously_new_record?` to show if a record was new before the last save.
|
482
759
|
|
483
|
-
*
|
760
|
+
*Tom Ward*
|
484
761
|
|
485
|
-
*
|
762
|
+
* Support descending order for `find_each`, `find_in_batches`, and `in_batches`.
|
486
763
|
|
487
|
-
|
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.
|
488
765
|
|
489
|
-
|
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.
|
490
767
|
|
491
|
-
|
768
|
+
Pass `order: :desc` to yield batches in descending order. The default remains `order: :asc`.
|
492
769
|
|
493
|
-
|
770
|
+
```ruby
|
771
|
+
Person.find_each(order: :desc) do |person|
|
772
|
+
person.party_all_night!
|
773
|
+
end
|
774
|
+
```
|
494
775
|
|
495
|
-
*
|
776
|
+
*Alexey Vasiliev*
|
496
777
|
|
497
|
-
*
|
778
|
+
* Fix `insert_all` with enum values.
|
498
779
|
|
499
|
-
|
780
|
+
Fixes #38716.
|
500
781
|
|
501
|
-
*
|
782
|
+
*Joel Blum*
|
502
783
|
|
503
|
-
|
784
|
+
* Add support for `db:rollback:name` for multiple database applications.
|
504
785
|
|
505
|
-
|
786
|
+
Multiple database applications will now raise if `db:rollback` is call and recommend using the `db:rollback:[NAME]` to rollback migrations.
|
506
787
|
|
507
|
-
*
|
788
|
+
*Eileen M. Uchitelle*
|
508
789
|
|
509
|
-
|
790
|
+
* `Relation#pick` now uses already loaded results instead of making another query.
|
510
791
|
|
511
|
-
*
|
792
|
+
*Eugene Kenny*
|
512
793
|
|
513
|
-
|
794
|
+
* Deprecate using `return`, `break` or `throw` to exit a transaction block after writes.
|
514
795
|
|
515
|
-
*
|
796
|
+
*Dylan Thacker-Smith*
|
516
797
|
|
517
|
-
|
798
|
+
* Dump the schema or structure of a database when calling `db:migrate:name`.
|
518
799
|
|
519
|
-
|
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.
|
520
801
|
|
521
|
-
|
522
|
-
format for InnoDB tables. The default setting is `DYNAMIC`.
|
523
|
-
The row format is required for indexing on `varchar(255)` with `utf8mb4` columns.
|
802
|
+
Going forward, calls to `rails db:migrate:name` will dump the schema (or structure) of the database being migrated.
|
524
803
|
|
525
|
-
*
|
804
|
+
*Kyle Thompson*
|
526
805
|
|
527
|
-
*
|
806
|
+
* Reset the `ActiveRecord::Base` connection after `rails db:migrate:name`.
|
528
807
|
|
529
|
-
|
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.
|
530
809
|
|
531
|
-
*
|
810
|
+
*Kyle Thompson*
|
532
811
|
|
533
|
-
|
812
|
+
* Disallow calling `connected_to` on subclasses of `ActiveRecord::Base`.
|
534
813
|
|
535
|
-
|
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.
|
536
815
|
|
537
|
-
*
|
816
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
538
817
|
|
539
|
-
*
|
818
|
+
* Add support for horizontal sharding to `connects_to` and `connected_to`.
|
540
819
|
|
541
|
-
|
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.
|
821
|
+
|
822
|
+
Usage:
|
823
|
+
|
824
|
+
Given the following configuration:
|
542
825
|
|
543
|
-
|
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
|
+
```
|
544
834
|
|
545
|
-
|
546
|
-
you're building out multiple databases and want to make sure you're not sending
|
547
|
-
writes when you want a read.
|
835
|
+
Connect to multiple shards:
|
548
836
|
|
549
|
-
|
550
|
-
|
551
|
-
|
837
|
+
```ruby
|
838
|
+
class ApplicationRecord < ActiveRecord::Base
|
839
|
+
self.abstract_class = true
|
552
840
|
|
553
|
-
|
554
|
-
|
555
|
-
|
841
|
+
connects_to shards: {
|
842
|
+
default: { writing: :primary },
|
843
|
+
shard_one: { writing: :primary_shard_one }
|
844
|
+
}
|
845
|
+
```
|
556
846
|
|
557
|
-
|
847
|
+
Swap between shards in your controller / model code:
|
558
848
|
|
559
|
-
|
849
|
+
```ruby
|
850
|
+
ActiveRecord::Base.connected_to(shard: :shard_one) do
|
851
|
+
# Read from shard one
|
852
|
+
end
|
853
|
+
```
|
560
854
|
|
561
|
-
|
855
|
+
The horizontal sharding API also supports read replicas. See guides for more details.
|
562
856
|
|
563
|
-
*
|
857
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
564
858
|
|
565
|
-
|
859
|
+
* Deprecate `spec_name` in favor of `name` on database configurations.
|
566
860
|
|
567
|
-
|
861
|
+
The accessors for `spec_name` on `configs_for` and `DatabaseConfig` are deprecated. Please use `name` instead.
|
862
|
+
|
863
|
+
Deprecated behavior:
|
568
864
|
|
569
|
-
|
865
|
+
```ruby
|
866
|
+
db_config = ActiveRecord::Base.configs_for(env_name: "development", spec_name: "primary")
|
867
|
+
db_config.spec_name
|
868
|
+
```
|
570
869
|
|
571
|
-
|
572
|
-
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
870
|
+
New behavior:
|
573
871
|
|
574
872
|
```ruby
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
end
|
579
|
-
end
|
873
|
+
db_config = ActiveRecord::Base.configs_for(env_name: "development", name: "primary")
|
874
|
+
db_config.name
|
875
|
+
```
|
580
876
|
|
581
|
-
|
582
|
-
self.table_name = "developers"
|
877
|
+
*Eileen M. Uchitelle*
|
583
878
|
|
584
|
-
|
879
|
+
* Add additional database-specific rake tasks for multi-database users.
|
585
880
|
|
586
|
-
|
587
|
-
|
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:
|
588
883
|
|
589
|
-
|
590
|
-
|
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
|
+
```
|
895
|
+
|
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:
|
591
898
|
|
592
|
-
|
593
|
-
|
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
|
594
915
|
```
|
595
916
|
|
596
|
-
*
|
917
|
+
*Kyle Thompson*
|
597
918
|
|
598
|
-
*
|
919
|
+
* Add support for `strict_loading` mode on association declarations.
|
599
920
|
|
600
|
-
|
601
|
-
explicit order clause, ActiveRecord sorts records by primary key. This can
|
602
|
-
result in unpredictable and surprising behaviour when the primary key is
|
603
|
-
not an auto-incrementing integer, for example when it's a UUID. This change
|
604
|
-
makes it possible to override the column used for implicit ordering such
|
605
|
-
that `first` and `last` will return more predictable results.
|
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.
|
606
922
|
|
607
|
-
|
923
|
+
Usage:
|
608
924
|
|
609
|
-
|
610
|
-
|
611
|
-
|
925
|
+
```ruby
|
926
|
+
class Developer < ApplicationRecord
|
927
|
+
has_many :projects, strict_loading: true
|
928
|
+
end
|
612
929
|
|
613
|
-
|
930
|
+
dev = Developer.first
|
931
|
+
dev.projects.first
|
932
|
+
# => ActiveRecord::StrictLoadingViolationError: The projects association is marked as strict_loading and cannot be lazily loaded.
|
933
|
+
```
|
614
934
|
|
615
|
-
*
|
935
|
+
*Kevin Deisz*
|
616
936
|
|
617
|
-
|
937
|
+
* Add support for `strict_loading` mode to prevent lazy loading of records.
|
618
938
|
|
619
|
-
|
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.
|
620
940
|
|
621
|
-
|
941
|
+
Usage:
|
622
942
|
|
623
|
-
|
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
|
+
```
|
624
948
|
|
625
|
-
|
949
|
+
*Eileen M. Uchitelle*, *Aaron Patterson*
|
626
950
|
|
627
|
-
|
951
|
+
* Add support for PostgreSQL 11+ partitioned indexes when using `upsert_all`.
|
628
952
|
|
629
|
-
|
953
|
+
*Sebastián Palma*
|
630
954
|
|
631
|
-
|
955
|
+
* Adds support for `if_not_exists` to `add_column` and `if_exists` to `remove_column`.
|
632
956
|
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
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.
|
958
|
+
|
959
|
+
Example Usage:
|
960
|
+
|
961
|
+
```ruby
|
962
|
+
class AddColumnTitle < ActiveRecord::Migration[6.1]
|
963
|
+
def change
|
964
|
+
add_column :posts, :title, :string, if_not_exists: true
|
637
965
|
end
|
638
966
|
end
|
639
967
|
```
|
640
968
|
|
641
|
-
|
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
|
+
```
|
642
976
|
|
643
|
-
*
|
977
|
+
*Eileen M. Uchitelle*
|
644
978
|
|
645
|
-
|
979
|
+
* Regexp-escape table name for MS SQL Server.
|
646
980
|
|
647
|
-
|
648
|
-
t.string :title
|
649
|
-
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.
|
650
982
|
|
651
|
-
|
983
|
+
*Larry Reid*
|
652
984
|
|
653
|
-
|
654
|
-
...
|
655
|
-
)
|
985
|
+
* Store advisory locks on their own named connection.
|
656
986
|
|
657
|
-
|
658
|
-
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.
|
659
988
|
|
660
|
-
|
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.
|
661
990
|
|
662
|
-
*
|
991
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
663
992
|
|
664
|
-
|
993
|
+
* Allow schema cache path to be defined in the database configuration file.
|
665
994
|
|
666
|
-
|
995
|
+
For example:
|
667
996
|
|
668
|
-
|
997
|
+
```yaml
|
998
|
+
development:
|
999
|
+
adapter: postgresql
|
1000
|
+
database: blog_development
|
1001
|
+
pool: 5
|
1002
|
+
schema_cache_path: tmp/schema/main.yml
|
1003
|
+
```
|
669
1004
|
|
670
|
-
*
|
671
|
-
if the attribute does not exist.
|
1005
|
+
*Katrina Owen*
|
672
1006
|
|
673
|
-
|
1007
|
+
* Deprecate `#remove_connection` in favor of `#remove_connection_pool` when called on the handler.
|
674
1008
|
|
675
|
-
|
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.
|
676
1010
|
|
677
|
-
|
678
|
-
User.connected_to(database: { writing: "postgres://foo" }) do
|
679
|
-
User.create!(name: "Gannon")
|
680
|
-
end
|
1011
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
681
1012
|
|
682
|
-
|
683
|
-
User.connected_to(database: { reading: config }) do
|
684
|
-
User.count
|
685
|
-
end
|
686
|
-
````
|
1013
|
+
* Deprecate `#default_hash` and it's alias `#[]` on database configurations.
|
687
1014
|
|
688
|
-
|
1015
|
+
Applications should use `configs_for`. `#default_hash` and `#[]` will be removed in 6.2.
|
689
1016
|
|
690
|
-
*
|
1017
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
691
1018
|
|
692
|
-
|
1019
|
+
* Add scale support to `ActiveRecord::Validations::NumericalityValidator`.
|
693
1020
|
|
694
|
-
|
1021
|
+
*Gannon McGibbon*
|
695
1022
|
|
696
|
-
|
1023
|
+
* Find orphans by looking for missing relations through chaining `where.missing`:
|
697
1024
|
|
698
|
-
|
1025
|
+
Before:
|
699
1026
|
|
700
|
-
|
701
|
-
|
1027
|
+
```ruby
|
1028
|
+
Post.left_joins(:author).where(authors: { id: nil })
|
1029
|
+
```
|
702
1030
|
|
703
|
-
|
1031
|
+
After:
|
704
1032
|
|
705
|
-
|
1033
|
+
```ruby
|
1034
|
+
Post.where.missing(:author)
|
1035
|
+
```
|
706
1036
|
|
707
|
-
*
|
1037
|
+
*Tom Rossi*
|
708
1038
|
|
709
|
-
|
1039
|
+
* Ensure `:reading` connections always raise if a write is attempted.
|
710
1040
|
|
711
|
-
|
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`.
|
712
1042
|
|
713
|
-
*
|
1043
|
+
*Eileen M. Uchitelle*
|
714
1044
|
|
715
|
-
|
1045
|
+
* Deprecate `"primary"` as the `connection_specification_name` for `ActiveRecord::Base`.
|
716
1046
|
|
717
|
-
|
718
|
-
class AnimalsModel < ApplicationRecord
|
719
|
-
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"`.
|
720
1048
|
|
721
|
-
|
722
|
-
end
|
1049
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
723
1050
|
|
724
|
-
|
725
|
-
|
726
|
-
end
|
727
|
-
```
|
1051
|
+
* Add `ActiveRecord::Validations::NumericalityValidator` with
|
1052
|
+
support for casting floats using a database columns' precision value.
|
728
1053
|
|
729
|
-
|
730
|
-
a database that the model didn't connect to. Connecting to the database in this block is
|
731
|
-
useful when you have another defined connection, for example `slow_replica` that you don't
|
732
|
-
want to connect to by default but need in the console, or a specific code block.
|
1054
|
+
*Gannon McGibbon*
|
733
1055
|
|
734
|
-
|
735
|
-
ActiveRecord::
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
```
|
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.
|
740
1061
|
|
741
|
-
|
742
|
-
ActiveRecord::Base.connected_to(database: :slow_replica) do
|
743
|
-
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
|
744
|
-
end
|
745
|
-
```
|
1062
|
+
Fixes #38078.
|
746
1063
|
|
747
|
-
*
|
1064
|
+
*Aaron Lipman*
|
748
1065
|
|
749
|
-
*
|
1066
|
+
* Skip test database when running `db:create` or `db:drop` in development
|
1067
|
+
with `DATABASE_URL` set.
|
750
1068
|
|
751
|
-
|
752
|
-
commit checks that only valid definition values are provided, those can
|
753
|
-
be a Hash, an array of Symbols or an array of Strings. Otherwise it
|
754
|
-
raises an `ArgumentError`.
|
1069
|
+
*Brian Buchalter*
|
755
1070
|
|
756
|
-
|
1071
|
+
* Don't allow mutations on the database configurations hash.
|
757
1072
|
|
758
|
-
|
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.
|
759
1074
|
|
760
|
-
|
1075
|
+
Before:
|
761
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")
|
762
1080
|
```
|
763
|
-
class Post < ActiveRecord::Base
|
764
|
-
has_one :category
|
765
|
-
belongs_to :author
|
766
|
-
has_many :comments
|
767
|
-
end
|
768
1081
|
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
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)
|
773
1088
|
```
|
774
1089
|
|
775
|
-
*
|
1090
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
776
1091
|
|
777
|
-
*
|
778
|
-
With this change you can create indexes while adding new
|
779
|
-
columns into the existing tables.
|
1092
|
+
* Remove `:connection_id` from the `sql.active_record` notification.
|
780
1093
|
|
781
|
-
|
1094
|
+
*Aaron Patterson*, *Rafael Mendonça França*
|
782
1095
|
|
783
|
-
|
784
|
-
t.string :country_code, index: true
|
785
|
-
end
|
1096
|
+
* The `:name` key will no longer be returned as part of `DatabaseConfig#configuration_hash`. Please use `DatabaseConfig#owner_name` instead.
|
786
1097
|
|
787
|
-
*
|
1098
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
788
1099
|
|
789
|
-
*
|
1100
|
+
* ActiveRecord's `belongs_to_required_by_default` flag can now be set per model.
|
790
1101
|
|
791
|
-
|
792
|
-
|
1102
|
+
You can now opt-out/opt-in specific models from having their associations required
|
1103
|
+
by default.
|
793
1104
|
|
794
|
-
|
1105
|
+
This change is meant to ease the process of migrating all your models to have
|
1106
|
+
their association required.
|
795
1107
|
|
796
|
-
*
|
1108
|
+
*Edouard Chin*
|
797
1109
|
|
798
|
-
|
1110
|
+
* The `connection_config` method has been deprecated, please use `connection_db_config` instead which will return a `DatabaseConfigurations::DatabaseConfig` instead of a `Hash`.
|
799
1111
|
|
800
|
-
*
|
1112
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
801
1113
|
|
802
|
-
|
1114
|
+
* Retain explicit selections on the base model after applying `includes` and `joins`.
|
803
1115
|
|
804
|
-
|
1116
|
+
Resolves #34889.
|
805
1117
|
|
806
|
-
|
1118
|
+
*Patrick Rebsch*
|
807
1119
|
|
808
|
-
|
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.
|
809
1121
|
|
810
|
-
*
|
1122
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
811
1123
|
|
812
|
-
|
1124
|
+
* Allow attributes to be fetched from Arel node groupings.
|
813
1125
|
|
814
|
-
*
|
1126
|
+
*Jeff Emminger*, *Gannon McGibbon*
|
815
1127
|
|
816
|
-
|
817
|
-
create_table :users do |t|
|
818
|
-
t.string :email
|
819
|
-
end
|
1128
|
+
* A database URL can now contain a querystring value that contains an equal sign. This is needed to support passing PostgreSQL `options`.
|
820
1129
|
|
821
|
-
|
822
|
-
```
|
1130
|
+
*Joshua Flanagan*
|
823
1131
|
|
824
|
-
|
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`.
|
825
1133
|
|
826
|
-
*
|
1134
|
+
*John Crepezzi*
|
827
1135
|
|
828
|
-
|
1136
|
+
* Specifying `implicit_order_column` now subsorts the records by primary key if available to ensure deterministic results.
|
829
1137
|
|
830
|
-
*
|
1138
|
+
*Paweł Urbanek*
|
831
1139
|
|
832
|
-
*
|
1140
|
+
* `where(attr => [])` now loads an empty result without making a query.
|
833
1141
|
|
834
|
-
*
|
1142
|
+
*John Hawthorn*
|
835
1143
|
|
836
|
-
*
|
1144
|
+
* Fixed the performance regression for `primary_keys` introduced MySQL 8.0.
|
837
1145
|
|
838
|
-
|
839
|
-
The previous default 3-Byte encoding character set `utf8` is not enough to support them.
|
1146
|
+
*Hiroyuki Ishii*
|
840
1147
|
|
841
|
-
|
1148
|
+
* Add support for `belongs_to` to `has_many` inversing.
|
842
1149
|
|
843
|
-
*
|
1150
|
+
*Gannon McGibbon*
|
844
1151
|
|
845
|
-
|
1152
|
+
* Allow length configuration for `has_secure_token` method. The minimum length
|
1153
|
+
is set at 24 characters.
|
846
1154
|
|
847
|
-
|
848
|
-
sensitive values of database columns when calling `#inspect`.
|
849
|
-
We also added `ActiveRecord::Base::filter_attributes`/`=` in order to
|
850
|
-
specify sensitive attributes to specific model.
|
1155
|
+
Before:
|
851
1156
|
|
1157
|
+
```ruby
|
1158
|
+
has_secure_token :auth_token
|
852
1159
|
```
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
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
|
857
1167
|
```
|
858
1168
|
|
859
|
-
*
|
1169
|
+
*Bernardo de Araujo*
|
860
1170
|
|
861
|
-
* Deprecate `
|
862
|
-
`indexes_per_table`, `columns_per_multicolumn_index`, `sql_query_length`,
|
863
|
-
and `joins_per_query` methods in `DatabaseLimits`.
|
1171
|
+
* Deprecate `DatabaseConfigurations#to_h`. These connection hashes are still available via `ActiveRecord::Base.configurations.configs_for`.
|
864
1172
|
|
865
|
-
*
|
1173
|
+
*Eileen Uchitelle*, *John Crepezzi*
|
866
1174
|
|
867
|
-
* `
|
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.
|
868
1176
|
|
869
|
-
|
870
|
-
is an inflexible data model. In order to improve multiple-database
|
871
|
-
handling in Rails, we've changed this to return an object. Some methods
|
872
|
-
are provided to make the object behave hash-like in order to ease the
|
873
|
-
transition process. Since most applications don't manipulate the hash
|
874
|
-
we've decided to add backwards-compatible functionality that will throw
|
875
|
-
a deprecation warning if used, however calling `ActiveRecord::Base.configurations`
|
876
|
-
will use the new version internally and externally.
|
1177
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
877
1178
|
|
878
|
-
|
1179
|
+
* Allow column names to be passed to `remove_index` positionally along with other options.
|
879
1180
|
|
880
|
-
|
881
|
-
development:
|
882
|
-
adapter: sqlite3
|
883
|
-
database: db/development.sqlite3
|
884
|
-
```
|
1181
|
+
Passing other options can be necessary to make `remove_index` correctly reversible.
|
885
1182
|
|
886
|
-
|
1183
|
+
Before:
|
887
1184
|
|
888
|
-
|
889
|
-
|
890
|
-
|
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
|
891
1189
|
|
892
|
-
|
1190
|
+
After:
|
893
1191
|
|
894
|
-
|
895
|
-
#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
896
|
-
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
897
|
-
@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
|
898
|
-
]
|
899
|
-
```
|
1192
|
+
remove_index :reports, :report_id, unique: true # => works
|
900
1193
|
|
901
|
-
|
902
|
-
calling hash methods on the `configurations` hash directly, a new method `configs_for` has
|
903
|
-
been provided that allows you to select the correct configuration. `env_name` and
|
904
|
-
`spec_name` arguments are optional. For example, these return an array of
|
905
|
-
database config objects for the requested environment and a single database config object
|
906
|
-
will be returned for the requested environment and specification name respectively.
|
1194
|
+
*Eugene Kenny*
|
907
1195
|
|
908
|
-
|
909
|
-
ActiveRecord::Base.configurations.configs_for(env_name: "development")
|
910
|
-
ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
|
911
|
-
```
|
1196
|
+
* Allow bulk `ALTER` statements to drop and recreate indexes with the same name.
|
912
1197
|
|
913
|
-
*
|
1198
|
+
*Eugene Kenny*
|
914
1199
|
|
915
|
-
*
|
1200
|
+
* `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
|
916
1201
|
|
917
|
-
|
918
|
-
production:
|
919
|
-
adapter: postgresql
|
920
|
-
advisory_locks: false
|
921
|
-
```
|
1202
|
+
*Eugene Kenny*
|
922
1203
|
|
923
|
-
|
1204
|
+
* Call `while_preventing_writes` directly from `connected_to`.
|
924
1205
|
|
925
|
-
|
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)`.
|
926
1207
|
|
927
|
-
|
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.
|
928
1209
|
|
929
|
-
*
|
1210
|
+
*Eileen M. Uchitelle*
|
930
1211
|
|
931
|
-
|
1212
|
+
* Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter in the edge case when the query is terminated during filesort.
|
932
1213
|
|
933
|
-
|
1214
|
+
*Kir Shatrov*
|
934
1215
|
|
935
|
-
|
1216
|
+
* Stop trying to read yaml file fixtures when loading Active Record fixtures.
|
936
1217
|
|
937
|
-
*
|
938
|
-
seed load in environments without Rails and custom DB configuration
|
1218
|
+
*Gannon McGibbon*
|
939
1219
|
|
940
|
-
|
1220
|
+
* Deprecate `.reorder(nil)` with `.first` / `.first!` taking non-deterministic result.
|
941
1221
|
|
942
|
-
|
1222
|
+
To continue taking non-deterministic result, use `.take` / `.take!` instead.
|
943
1223
|
|
944
|
-
*
|
1224
|
+
*Ryuta Kamizono*
|
945
1225
|
|
946
|
-
*
|
1226
|
+
* Preserve user supplied joins order as much as possible.
|
1227
|
+
|
1228
|
+
Fixes #36761, #34328, #24281, #12953.
|
947
1229
|
|
948
1230
|
*Ryuta Kamizono*
|
949
1231
|
|
950
|
-
*
|
1232
|
+
* Allow `matches_regex` and `does_not_match_regexp` on the MySQL Arel visitor.
|
951
1233
|
|
952
|
-
|
1234
|
+
*James Pearson*
|
953
1235
|
|
954
|
-
|
1236
|
+
* Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section.
|
955
1237
|
|
956
|
-
*
|
1238
|
+
*Tongfei Gao*
|
957
1239
|
|
958
|
-
|
1240
|
+
* Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
|
959
1241
|
|
960
|
-
*
|
1242
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
961
1243
|
|
962
|
-
|
1244
|
+
* Add a warning for enum elements with 'not_' prefix.
|
963
1245
|
|
964
|
-
|
1246
|
+
class Foo
|
1247
|
+
enum status: [:sent, :not_sent]
|
1248
|
+
end
|
965
1249
|
|
966
|
-
*
|
1250
|
+
*Edu Depetris*
|
967
1251
|
|
968
|
-
|
1252
|
+
* Make currency symbols optional for money column type in PostgreSQL.
|
969
1253
|
|
970
|
-
*
|
971
|
-
use loaded association ids if present.
|
1254
|
+
*Joel Schneider*
|
972
1255
|
|
973
|
-
|
1256
|
+
* Add support for beginless ranges, introduced in Ruby 2.7.
|
974
1257
|
|
975
|
-
*
|
1258
|
+
*Josh Goodall*
|
976
1259
|
|
977
|
-
|
1260
|
+
* Add `database_exists?` method to connection adapters to check if a database exists.
|
978
1261
|
|
979
|
-
*
|
1262
|
+
*Guilherme Mansur*
|
980
1263
|
|
981
|
-
|
1264
|
+
* Loading the schema for a model that has no `table_name` raises a `TableNotSpecified` error.
|
982
1265
|
|
983
|
-
|
1266
|
+
*Guilherme Mansur*, *Eugene Kenny*
|
984
1267
|
|
985
|
-
|
1268
|
+
* PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
|
986
1269
|
|
987
|
-
|
1270
|
+
Fixes #36022.
|
988
1271
|
|
989
|
-
*
|
1272
|
+
*Ryuta Kamizono*
|
990
1273
|
|
991
|
-
*
|
1274
|
+
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
992
1275
|
|
993
|
-
|
1276
|
+
Fixes #36465.
|
994
1277
|
|
995
|
-
*
|
1278
|
+
*Jeff Doering*
|
996
1279
|
|
997
|
-
|
1280
|
+
* Add support for multiple databases to `rails db:abort_if_pending_migrations`.
|
998
1281
|
|
999
|
-
*
|
1282
|
+
*Mark Lee*
|
1000
1283
|
|
1001
|
-
|
1284
|
+
* Fix sqlite3 collation parsing when using decimal columns.
|
1002
1285
|
|
1003
|
-
*
|
1004
|
-
`ActiveRecord::Base.find_or_create_by`/`!` by leaning on unique constraints in the database.
|
1286
|
+
*Martin R. Schuster*
|
1005
1287
|
|
1006
|
-
|
1288
|
+
* Fix invalid schema when primary key column has a comment.
|
1007
1289
|
|
1008
|
-
|
1290
|
+
Fixes #29966.
|
1009
1291
|
|
1010
|
-
*
|
1292
|
+
*Guilherme Goettems Schneider*
|
1293
|
+
|
1294
|
+
* Fix table comment also being applied to the primary key column.
|
1295
|
+
|
1296
|
+
*Guilherme Goettems Schneider*
|
1297
|
+
|
1298
|
+
* Allow generated `create_table` migrations to include or skip timestamps.
|
1299
|
+
|
1300
|
+
*Michael Duchemin*
|
1011
1301
|
|
1012
1302
|
|
1013
|
-
Please check [
|
1303
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
|