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