activerecord 5.2.7.1 → 6.1.4.6
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 +1145 -575
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +9 -8
- data/lib/active_record/association_relation.rb +30 -10
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +100 -41
- data/lib/active_record/associations/association_scope.rb +23 -21
- data/lib/active_record/associations/belongs_to_association.rb +55 -48
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
- data/lib/active_record/associations/builder/association.rb +45 -22
- data/lib/active_record/associations/builder/belongs_to.rb +29 -59
- data/lib/active_record/associations/builder/collection_association.rb +8 -17
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -2
- data/lib/active_record/associations/builder/has_one.rb +33 -2
- data/lib/active_record/associations/builder/singular_association.rb +3 -1
- data/lib/active_record/associations/collection_association.rb +31 -29
- data/lib/active_record/associations/collection_proxy.rb +25 -21
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +26 -13
- data/lib/active_record/associations/has_many_through_association.rb +24 -18
- data/lib/active_record/associations/has_one_association.rb +43 -31
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
- data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +91 -60
- data/lib/active_record/associations/preloader/association.rb +71 -43
- data/lib/active_record/associations/preloader/through_association.rb +49 -40
- data/lib/active_record/associations/preloader.rb +47 -34
- data/lib/active_record/associations/singular_association.rb +3 -17
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +137 -25
- data/lib/active_record/attribute_assignment.rb +17 -19
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -40
- data/lib/active_record/attribute_methods/primary_key.rb +20 -25
- data/lib/active_record/attribute_methods/query.rb +4 -8
- data/lib/active_record/attribute_methods/read.rb +14 -56
- data/lib/active_record/attribute_methods/serialization.rb +12 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +18 -34
- data/lib/active_record/attribute_methods.rb +81 -143
- data/lib/active_record/attributes.rb +46 -9
- data/lib/active_record/autosave_association.rb +57 -42
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +12 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
- data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
- data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
- data/lib/active_record/connection_adapters/column.rb +30 -12
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- 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 +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
- 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 +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_adapters.rb +52 -0
- data/lib/active_record/connection_handling.rb +293 -33
- data/lib/active_record/core.rb +334 -97
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/database_configurations.rb +272 -0
- 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 +3 -4
- data/lib/active_record/enum.rb +108 -36
- data/lib/active_record/errors.rb +62 -19
- data/lib/active_record/explain.rb +10 -6
- 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 +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +200 -481
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +53 -24
- data/lib/active_record/insert_all.rb +212 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +26 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +37 -23
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +35 -35
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +96 -44
- data/lib/active_record/migration/compatibility.rb +142 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +206 -157
- data/lib/active_record/model_schema.rb +148 -22
- data/lib/active_record/nested_attributes.rb +4 -7
- data/lib/active_record/no_touching.rb +8 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +267 -59
- data/lib/active_record/query_cache.rb +21 -4
- data/lib/active_record/querying.rb +40 -23
- data/lib/active_record/railtie.rb +115 -58
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +411 -80
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +109 -93
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +44 -35
- data/lib/active_record/relation/calculations.rb +157 -90
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +64 -39
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +32 -40
- data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +62 -45
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +476 -187
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +9 -9
- data/lib/active_record/relation/where_clause.rb +115 -62
- data/lib/active_record/relation.rb +379 -115
- data/lib/active_record/result.rb +64 -38
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +22 -41
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +54 -9
- data/lib/active_record/schema_migration.rb +7 -9
- data/lib/active_record/scoping/default.rb +4 -8
- data/lib/active_record/scoping/named.rb +17 -24
- data/lib/active_record/scoping.rb +8 -9
- 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 +49 -6
- data/lib/active_record/store.rb +88 -9
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +42 -43
- data/lib/active_record/tasks/database_tasks.rb +277 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
- data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +287 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +62 -118
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- 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.rb +10 -5
- data/lib/active_record/type_caster/connection.rb +15 -15
- data/lib/active_record/type_caster/map.rb +8 -8
- 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 +38 -30
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record.rb +13 -12
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +76 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
- data/lib/rails/generators/active_record/migration.rb +19 -2
- 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
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +117 -32
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
- data/lib/active_record/relation/where_clause_factory.rb +0 -34
data/CHANGELOG.md
CHANGED
@@ -1,44 +1,197 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails
|
6
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails
|
11
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails
|
16
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails
|
21
|
+
## Rails 6.1.4.2 (December 14, 2021) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails
|
26
|
+
## Rails 6.1.4.1 (August 19, 2021) ##
|
27
27
|
|
28
28
|
* No changes.
|
29
29
|
|
30
30
|
|
31
|
-
## Rails
|
31
|
+
## Rails 6.1.4 (June 24, 2021) ##
|
32
|
+
|
33
|
+
* Do not try to rollback transactions that failed due to a `ActiveRecord::TransactionRollbackError`.
|
34
|
+
|
35
|
+
*Jamie McCarthy*
|
36
|
+
|
37
|
+
* Raise an error if `pool_config` is `nil` in `set_pool_config`.
|
38
|
+
|
39
|
+
*Eileen M. Uchitelle*
|
40
|
+
|
41
|
+
* Fix compatibility with `psych >= 4`.
|
42
|
+
|
43
|
+
Starting in Psych 4.0.0 `YAML.load` behaves like `YAML.safe_load`. To preserve compatibility
|
44
|
+
Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
|
45
|
+
|
46
|
+
*Jean Boussier*
|
47
|
+
|
48
|
+
* Support using replicas when using `rails dbconsole`.
|
49
|
+
|
50
|
+
*Christopher Thornton*
|
51
|
+
|
52
|
+
* Restore connection pools after transactional tests.
|
53
|
+
|
54
|
+
*Eugene Kenny*
|
55
|
+
|
56
|
+
* Change `upsert_all` to fails cleanly for MySQL when `:unique_by` is used.
|
57
|
+
|
58
|
+
*Bastian Bartmann*
|
59
|
+
|
60
|
+
* Fix user-defined `self.default_scope` to respect table alias.
|
61
|
+
|
62
|
+
*Ryuta Kamizono*
|
63
|
+
|
64
|
+
* Clear `@cache_keys` cache after `update_all`, `delete_all`, `destroy_all`.
|
65
|
+
|
66
|
+
*Ryuta Kamizono*
|
67
|
+
|
68
|
+
* Changed Arel predications `contains` and `overlaps` to use
|
69
|
+
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
70
|
+
|
71
|
+
*Bradley Priest*
|
72
|
+
|
73
|
+
* Fix `merge` when the `where` clauses have string contents.
|
74
|
+
|
75
|
+
*Ryuta Kamizono*
|
76
|
+
|
77
|
+
* Fix rollback of parent destruction with nested `dependent: :destroy`.
|
78
|
+
|
79
|
+
*Jacopo Beschi*
|
80
|
+
|
81
|
+
* Fix binds logging for `"WHERE ... IN ..."` statements.
|
82
|
+
|
83
|
+
*Ricardo Díaz*
|
84
|
+
|
85
|
+
* Handle `false` in relation strict loading checks.
|
86
|
+
|
87
|
+
Previously when a model had strict loading set to true and then had a
|
88
|
+
relation set `strict_loading` to false the false wasn't considered when
|
89
|
+
deciding whether to raise/warn about strict loading.
|
90
|
+
|
91
|
+
```
|
92
|
+
class Dog < ActiveRecord::Base
|
93
|
+
self.strict_loading_by_default = true
|
94
|
+
|
95
|
+
has_many :treats, strict_loading: false
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
In the example, `dog.treats` would still raise even though
|
100
|
+
`strict_loading` was set to false. This is a bug effecting more than
|
101
|
+
Active Storage which is why I made this PR superceeding #41461. We need
|
102
|
+
to fix this for all applications since the behavior is a little
|
103
|
+
surprising. I took the test from ##41461 and the code suggestion from #41453
|
104
|
+
with some additions.
|
105
|
+
|
106
|
+
*Eileen M. Uchitelle*, *Radamés Roriz*
|
107
|
+
|
108
|
+
* Fix numericality validator without precision.
|
109
|
+
|
110
|
+
*Ryuta Kamizono*
|
111
|
+
|
112
|
+
* Fix aggregate attribute on Enum types.
|
113
|
+
|
114
|
+
*Ryuta Kamizono*
|
115
|
+
|
116
|
+
* Fix `CREATE INDEX` statement generation for PostgreSQL.
|
117
|
+
|
118
|
+
*eltongo*
|
119
|
+
|
120
|
+
* Fix where clause on enum attribute when providing array of strings.
|
121
|
+
|
122
|
+
*Ryuta Kamizono*
|
123
|
+
|
124
|
+
* Fix `unprepared_statement` to work it when nesting.
|
125
|
+
|
126
|
+
*Ryuta Kamizono*
|
127
|
+
|
128
|
+
|
129
|
+
## Rails 6.1.3.2 (May 05, 2021) ##
|
32
130
|
|
33
131
|
* No changes.
|
34
132
|
|
35
133
|
|
36
|
-
## Rails
|
134
|
+
## Rails 6.1.3.1 (March 26, 2021) ##
|
37
135
|
|
38
136
|
* No changes.
|
39
137
|
|
40
138
|
|
41
|
-
## Rails
|
139
|
+
## Rails 6.1.3 (February 17, 2021) ##
|
140
|
+
|
141
|
+
* Fix the MySQL adapter to always set the right collation and charset
|
142
|
+
to the connection session.
|
143
|
+
|
144
|
+
*Rafael Mendonça França*
|
145
|
+
|
146
|
+
* Fix MySQL adapter handling of time objects when prepared statements
|
147
|
+
are enabled.
|
148
|
+
|
149
|
+
*Rafael Mendonça França*
|
150
|
+
|
151
|
+
* Fix scoping in enum fields using conditions that would generate
|
152
|
+
an `IN` clause.
|
153
|
+
|
154
|
+
*Ryuta Kamizono*
|
155
|
+
|
156
|
+
* Skip optimised #exist? query when #include? is called on a relation
|
157
|
+
with a having clause
|
158
|
+
|
159
|
+
Relations that have aliased select values AND a having clause that
|
160
|
+
references an aliased select value would generate an error when
|
161
|
+
#include? was called, due to an optimisation that would generate
|
162
|
+
call #exists? on the relation instead, which effectively alters
|
163
|
+
the select values of the query (and thus removes the aliased select
|
164
|
+
values), but leaves the having clause intact. Because the having
|
165
|
+
clause is then referencing an aliased column that is no longer
|
166
|
+
present in the simplified query, an ActiveRecord::InvalidStatement
|
167
|
+
error was raised.
|
168
|
+
|
169
|
+
An sample query affected by this problem:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Author.select('COUNT(*) as total_posts', 'authors.*')
|
173
|
+
.joins(:posts)
|
174
|
+
.group(:id)
|
175
|
+
.having('total_posts > 2')
|
176
|
+
.include?(Author.first)
|
177
|
+
```
|
178
|
+
|
179
|
+
This change adds an addition check to the condition that skips the
|
180
|
+
simplified #exists? query, which simply checks for the presence of
|
181
|
+
a having clause.
|
182
|
+
|
183
|
+
Fixes #41417
|
184
|
+
|
185
|
+
*Michael Smart*
|
186
|
+
|
187
|
+
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
188
|
+
without Rails knowledge (e.g., if app gets kill -9d during long-running query or due to Rack::Timeout), app won't end
|
189
|
+
up in perpetual crash state for being inconsistent with Postgres.
|
190
|
+
|
191
|
+
*wbharding*, *Martin Tepper*
|
192
|
+
|
193
|
+
|
194
|
+
## Rails 6.1.2.1 (February 10, 2021) ##
|
42
195
|
|
43
196
|
* Fix possible DoS vector in PostgreSQL money type
|
44
197
|
|
@@ -53,999 +206,1416 @@
|
|
53
206
|
*Aaron Patterson*
|
54
207
|
|
55
208
|
|
56
|
-
## Rails
|
209
|
+
## Rails 6.1.2 (February 09, 2021) ##
|
57
210
|
|
58
|
-
*
|
211
|
+
* Fix timestamp type for sqlite3.
|
59
212
|
|
213
|
+
*Eileen M. Uchitelle*
|
60
214
|
|
61
|
-
|
215
|
+
* Make destroy async transactional.
|
62
216
|
|
63
|
-
|
217
|
+
An active record rollback could occur while enqueuing a job. In this
|
218
|
+
case the job would enqueue even though the database deletion
|
219
|
+
rolledback putting things in a funky state.
|
64
220
|
|
65
|
-
|
221
|
+
Now the jobs are only enqueued until after the db transaction has been committed.
|
66
222
|
|
67
|
-
*
|
223
|
+
*Cory Gwin*
|
68
224
|
|
225
|
+
* Fix malformed packet error in MySQL statement for connection configuration.
|
69
226
|
|
70
|
-
|
227
|
+
*robinroestenburg*
|
71
228
|
|
72
|
-
*
|
229
|
+
* Connection specification now passes the "url" key as a configuration for the
|
230
|
+
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
231
|
+
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
232
|
+
are assumed to be adapter specification urls.
|
73
233
|
|
234
|
+
Fixes #41137.
|
74
235
|
|
75
|
-
|
236
|
+
*Jonathan Bracy*
|
76
237
|
|
77
|
-
* Fix
|
238
|
+
* Fix granular connection swapping when there are multiple abstract classes.
|
78
239
|
|
79
|
-
|
80
|
-
associations, the callback for a `has_many` association was run while
|
81
|
-
another instance of the same callback on the same association hadn't
|
82
|
-
finished running. When control returned to the first instance of the
|
83
|
-
callback, the instance variable had changed, and subsequent associated
|
84
|
-
records weren't saved correctly. Specifically, the ID field for the
|
85
|
-
`belongs_to` corresponding to the `has_many` was `nil`.
|
240
|
+
*Eileen M. Uchitelle*
|
86
241
|
|
87
|
-
|
242
|
+
* Fix `find_by` with custom primary key for belongs_to association.
|
88
243
|
|
89
|
-
*
|
244
|
+
*Ryuta Kamizono*
|
90
245
|
|
91
|
-
*
|
246
|
+
* Add support for `rails console --sandbox` for multiple database applications.
|
92
247
|
|
93
|
-
|
248
|
+
*alpaca-tc*
|
249
|
+
|
250
|
+
* Fix `where` on polymorphic association with empty array.
|
94
251
|
|
95
252
|
*Ryuta Kamizono*
|
96
253
|
|
97
|
-
* Fix
|
254
|
+
* Fix preventing writes for `ApplicationRecord`.
|
98
255
|
|
99
|
-
*
|
256
|
+
*Eileen M. Uchitelle*
|
100
257
|
|
101
|
-
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
102
258
|
|
103
|
-
|
259
|
+
## Rails 6.1.1 (January 07, 2021) ##
|
104
260
|
|
105
|
-
|
106
|
-
|
107
|
-
* Assign all attributes before calling `build` to ensure the child record is visible in
|
108
|
-
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
261
|
+
* Fix fixtures loading when strict loading is enabled for the association.
|
109
262
|
|
110
|
-
|
263
|
+
*Alex Ghiculescu*
|
111
264
|
|
112
|
-
|
265
|
+
* Fix `where` with custom primary key for belongs_to association.
|
113
266
|
|
267
|
+
*Ryuta Kamizono*
|
114
268
|
|
115
|
-
|
269
|
+
* Fix `where` with aliased associations.
|
116
270
|
|
117
|
-
*
|
271
|
+
*Ryuta Kamizono*
|
118
272
|
|
119
|
-
|
273
|
+
* Fix `composed_of` with symbol mapping.
|
120
274
|
|
121
|
-
*
|
275
|
+
*Ryuta Kamizono*
|
122
276
|
|
123
|
-
*
|
277
|
+
* Don't skip money's type cast for pluck and calculations.
|
124
278
|
|
125
279
|
*Ryuta Kamizono*
|
126
280
|
|
127
|
-
*
|
128
|
-
|
129
|
-
Fixes #33624.
|
281
|
+
* Fix `where` on polymorphic association with non Active Record object.
|
130
282
|
|
131
283
|
*Ryuta Kamizono*
|
132
284
|
|
133
|
-
*
|
285
|
+
* Make sure `db:prepare` works even the schema file doesn't exist.
|
286
|
+
|
287
|
+
*Rafael Mendonça França*
|
134
288
|
|
135
|
-
|
289
|
+
* Fix complicated `has_many :through` with nested where condition.
|
136
290
|
|
137
291
|
*Ryuta Kamizono*
|
138
292
|
|
139
|
-
*
|
293
|
+
* Handle STI models for `has_many dependent: :destroy_async`.
|
140
294
|
|
141
|
-
*
|
295
|
+
*Muhammad Usman*
|
142
296
|
|
143
|
-
*
|
297
|
+
* Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
|
144
298
|
|
145
|
-
|
299
|
+
Previously, passing `false` would trigger the option validation logic
|
300
|
+
to throw an error saying :polymorphic would not be a valid option.
|
146
301
|
|
147
|
-
*
|
302
|
+
*glaszig*
|
148
303
|
|
149
|
-
|
304
|
+
* Allow adding nonnamed expression indexes to be revertible.
|
150
305
|
|
306
|
+
Fixes #40732.
|
151
307
|
|
152
|
-
|
308
|
+
Previously, the following code would raise an error, when executed while rolling back,
|
309
|
+
and the index name should be specified explicitly. Now, the index name is inferred
|
310
|
+
automatically.
|
153
311
|
|
154
|
-
|
312
|
+
```ruby
|
313
|
+
add_index(:items, "to_tsvector('english', description)")
|
314
|
+
```
|
315
|
+
|
316
|
+
*fatkodima*
|
155
317
|
|
156
318
|
|
157
|
-
## Rails
|
319
|
+
## Rails 6.1.0 (December 09, 2020) ##
|
158
320
|
|
159
|
-
*
|
321
|
+
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
160
322
|
|
161
|
-
|
323
|
+
Fixes #39065.
|
162
324
|
|
163
|
-
*
|
325
|
+
*Alex Ghiculescu*
|
164
326
|
|
165
|
-
|
327
|
+
* Change `attribute_for_inspect` to take `filter_attributes` in consideration.
|
166
328
|
|
167
|
-
*
|
329
|
+
*Rafael Mendonça França*
|
168
330
|
|
169
|
-
|
170
|
-
adapter.
|
331
|
+
* Fix odd behavior of inverse_of with multiple belongs_to to same class.
|
171
332
|
|
172
|
-
|
333
|
+
Fixes #35204.
|
173
334
|
|
174
|
-
*
|
335
|
+
*Tomoyuki Kai*
|
175
336
|
|
176
|
-
|
177
|
-
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
337
|
+
* Build predicate conditions with objects that delegate `#id` and primary key:
|
178
338
|
|
179
339
|
```ruby
|
180
|
-
class
|
181
|
-
|
182
|
-
|
340
|
+
class AdminAuthor
|
341
|
+
delegate_missing_to :@author
|
342
|
+
|
343
|
+
def initialize(author)
|
344
|
+
@author = author
|
183
345
|
end
|
184
346
|
end
|
185
347
|
|
186
|
-
|
187
|
-
|
348
|
+
Post.where(author: AdminAuthor.new(author))
|
349
|
+
```
|
188
350
|
|
189
|
-
|
351
|
+
*Sean Doyle*
|
190
352
|
|
191
|
-
|
192
|
-
end
|
353
|
+
* Add `connected_to_many` API.
|
193
354
|
|
194
|
-
|
195
|
-
developer.update_column :name, "name"
|
355
|
+
This API allows applications to connect to multiple databases at once without switching all of them or implementing a deeply nested stack.
|
196
356
|
|
197
|
-
|
198
|
-
puts loaded_developer.name # should be "Developer: name" but it's just "name"
|
199
|
-
```
|
200
|
-
|
201
|
-
*Dmitry Tsepelev*
|
357
|
+
Before:
|
202
358
|
|
203
|
-
|
359
|
+
AnimalsRecord.connected_to(role: :reading) do
|
360
|
+
MealsRecord.connected_to(role: :reading) do
|
361
|
+
Dog.first # read from animals replica
|
362
|
+
Dinner.first # read from meals replica
|
363
|
+
Person.first # read from primary writer
|
364
|
+
end
|
365
|
+
end
|
204
366
|
|
205
|
-
|
367
|
+
After:
|
206
368
|
|
207
|
-
|
208
|
-
|
369
|
+
ActiveRecord::Base.connected_to_many([AnimalsRecord, MealsRecord], role: :reading) do
|
370
|
+
Dog.first # read from animals replica
|
371
|
+
Dinner.first # read from meals replica
|
372
|
+
Person.first # read from primary writer
|
373
|
+
end
|
209
374
|
|
210
|
-
*
|
375
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
211
376
|
|
212
|
-
*
|
377
|
+
* Add option to raise or log for `ActiveRecord::StrictLoadingViolationError`.
|
213
378
|
|
214
|
-
|
379
|
+
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.
|
215
380
|
|
216
|
-
|
381
|
+
Set `config.active_record.action_on_strict_loading_violation` to `:log` errors instead of raising.
|
217
382
|
|
218
383
|
*Eileen M. Uchitelle*
|
219
384
|
|
220
|
-
*
|
385
|
+
* Allow the inverse of a `has_one` association that was previously autosaved to be loaded.
|
221
386
|
|
222
|
-
Fixes #
|
387
|
+
Fixes #34255.
|
223
388
|
|
224
|
-
*
|
389
|
+
*Steven Weber*
|
225
390
|
|
226
|
-
*
|
391
|
+
* Optimise the length of index names for polymorphic references by using the reference name rather than the type and id column names.
|
227
392
|
|
228
|
-
|
393
|
+
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.
|
229
394
|
|
230
|
-
|
395
|
+
This change reduces the chance of that happening by using the reference name, e.g. `index_my_table_on_my_reference`.
|
231
396
|
|
232
|
-
|
397
|
+
Fixes #38655.
|
233
398
|
|
234
|
-
*
|
399
|
+
*Luke Redpath*
|
235
400
|
|
236
|
-
|
401
|
+
* MySQL: Uniqueness validator now respects default database collation,
|
402
|
+
no longer enforce case sensitive comparison by default.
|
237
403
|
|
238
|
-
*
|
404
|
+
*Ryuta Kamizono*
|
239
405
|
|
240
|
-
|
406
|
+
* Remove deprecated methods from `ActiveRecord::ConnectionAdapters::DatabaseLimits`.
|
241
407
|
|
242
|
-
|
408
|
+
`column_name_length`
|
409
|
+
`table_name_length`
|
410
|
+
`columns_per_table`
|
411
|
+
`indexes_per_table`
|
412
|
+
`columns_per_multicolumn_index`
|
413
|
+
`sql_query_length`
|
414
|
+
`joins_per_query`
|
243
415
|
|
244
|
-
*
|
416
|
+
*Rafael Mendonça França*
|
245
417
|
|
246
|
-
*
|
418
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_multi_insert?`.
|
247
419
|
|
248
|
-
*
|
420
|
+
*Rafael Mendonça França*
|
249
421
|
|
250
|
-
*
|
422
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_foreign_keys_in_create?`.
|
251
423
|
|
252
|
-
*
|
424
|
+
*Rafael Mendonça França*
|
253
425
|
|
254
|
-
*
|
426
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#supports_ranges?`.
|
255
427
|
|
256
|
-
*
|
428
|
+
*Rafael Mendonça França*
|
257
429
|
|
430
|
+
* Remove deprecated `ActiveRecord::Base#update_attributes` and `ActiveRecord::Base#update_attributes!`.
|
258
431
|
|
259
|
-
|
432
|
+
*Rafael Mendonça França*
|
260
433
|
|
261
|
-
*
|
434
|
+
* Remove deprecated `migrations_path` argument in `ActiveRecord::ConnectionAdapter::SchemaStatements#assume_migrated_upto_version`.
|
262
435
|
|
436
|
+
*Rafael Mendonça França*
|
263
437
|
|
264
|
-
|
438
|
+
* Remove deprecated `config.active_record.sqlite3.represent_boolean_as_integer`.
|
265
439
|
|
266
|
-
*
|
440
|
+
*Rafael Mendonça França*
|
267
441
|
|
268
|
-
|
442
|
+
* `relation.create` does no longer leak scope to class level querying methods
|
443
|
+
in initialization block and callbacks.
|
269
444
|
|
270
|
-
|
445
|
+
Before:
|
271
446
|
|
272
|
-
|
447
|
+
User.where(name: "John").create do |john|
|
448
|
+
User.find_by(name: "David") # => nil
|
449
|
+
end
|
273
450
|
|
274
|
-
|
451
|
+
After:
|
275
452
|
|
276
|
-
|
453
|
+
User.where(name: "John").create do |john|
|
454
|
+
User.find_by(name: "David") # => #<User name: "David", ...>
|
455
|
+
end
|
277
456
|
|
278
|
-
*
|
457
|
+
*Ryuta Kamizono*
|
279
458
|
|
280
|
-
*
|
459
|
+
* Named scope chain does no longer leak scope to class level querying methods.
|
281
460
|
|
282
|
-
|
461
|
+
class User < ActiveRecord::Base
|
462
|
+
scope :david, -> { User.where(name: "David") }
|
463
|
+
end
|
464
|
+
|
465
|
+
Before:
|
466
|
+
|
467
|
+
User.where(name: "John").david
|
468
|
+
# SELECT * FROM users WHERE name = 'John' AND name = 'David'
|
283
469
|
|
284
|
-
|
470
|
+
After:
|
285
471
|
|
286
|
-
|
472
|
+
User.where(name: "John").david
|
473
|
+
# SELECT * FROM users WHERE name = 'David'
|
287
474
|
|
288
475
|
*Ryuta Kamizono*
|
289
476
|
|
290
|
-
*
|
477
|
+
* Remove deprecated methods from `ActiveRecord::DatabaseConfigurations`.
|
291
478
|
|
292
|
-
|
479
|
+
`fetch`
|
480
|
+
`each`
|
481
|
+
`first`
|
482
|
+
`values`
|
483
|
+
`[]=`
|
293
484
|
|
294
|
-
*
|
485
|
+
*Rafael Mendonça França*
|
295
486
|
|
296
|
-
|
487
|
+
* `where.not` now generates NAND predicates instead of NOR.
|
297
488
|
|
298
|
-
|
489
|
+
Before:
|
299
490
|
|
300
|
-
|
491
|
+
User.where.not(name: "Jon", role: "admin")
|
492
|
+
# SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
|
301
493
|
|
302
|
-
|
494
|
+
After:
|
303
495
|
|
304
|
-
|
496
|
+
User.where.not(name: "Jon", role: "admin")
|
497
|
+
# SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
|
305
498
|
|
306
|
-
*
|
499
|
+
*Rafael Mendonça França*
|
307
500
|
|
308
|
-
|
501
|
+
* Remove deprecated `ActiveRecord::Result#to_hash` method.
|
309
502
|
|
310
|
-
*
|
503
|
+
*Rafael Mendonça França*
|
311
504
|
|
312
|
-
*
|
505
|
+
* Deprecate `ActiveRecord::Base.allow_unsafe_raw_sql`.
|
313
506
|
|
314
|
-
*
|
507
|
+
*Rafael Mendonça França*
|
315
508
|
|
316
|
-
*
|
317
|
-
wrongly persists through record.
|
509
|
+
* Remove deprecated support for using unsafe raw SQL in `ActiveRecord::Relation` methods.
|
318
510
|
|
319
|
-
|
511
|
+
*Rafael Mendonça França*
|
320
512
|
|
321
|
-
|
513
|
+
* Allow users to silence the "Rails couldn't infer whether you are using multiple databases..."
|
514
|
+
message using `config.active_record.suppress_multiple_database_warning`.
|
322
515
|
|
323
|
-
*
|
324
|
-
query cache.
|
516
|
+
*Omri Gabay*
|
325
517
|
|
326
|
-
|
518
|
+
* Connections can be granularly switched for abstract classes when `connected_to` is called.
|
327
519
|
|
520
|
+
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.
|
328
521
|
|
329
|
-
|
522
|
+
Example usage:
|
330
523
|
|
331
|
-
|
524
|
+
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`.
|
332
525
|
|
333
|
-
|
526
|
+
```ruby
|
527
|
+
ActiveRecord::Base.connected_to(role: :reading) do
|
528
|
+
User.first # reads from default replica
|
529
|
+
Dog.first # reads from default replica
|
334
530
|
|
335
|
-
|
531
|
+
AnimalsRecord.connected_to(role: :writing, shard: :one) do
|
532
|
+
User.first # reads from default replica
|
533
|
+
Dog.first # reads from shard one primary
|
534
|
+
end
|
336
535
|
|
337
|
-
|
338
|
-
|
339
|
-
that precision. This behavior is now applied to time columns as well.
|
536
|
+
User.first # reads from default replica
|
537
|
+
Dog.first # reads from default replica
|
340
538
|
|
341
|
-
|
539
|
+
ApplicationRecord.connected_to(role: :writing, shard: :two) do
|
540
|
+
User.first # reads from shard two primary
|
541
|
+
Dog.first # reads from default replica
|
542
|
+
end
|
543
|
+
end
|
544
|
+
```
|
342
545
|
|
343
|
-
*
|
546
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
344
547
|
|
345
|
-
*
|
548
|
+
* Allow double-dash comment syntax when querying read-only databases
|
346
549
|
|
347
|
-
|
348
|
-
because until #24542 the quoting for time columns didn't remove the date
|
349
|
-
component. To ensure that values are consistent we now normalize the
|
350
|
-
date component to 2001-01-01 on reading and writing.
|
550
|
+
*James Adam*
|
351
551
|
|
352
|
-
|
552
|
+
* Add `values_at` method.
|
353
553
|
|
354
|
-
|
554
|
+
Returns an array containing the values associated with the given methods.
|
355
555
|
|
356
|
-
|
357
|
-
|
358
|
-
|
556
|
+
```ruby
|
557
|
+
topic = Topic.first
|
558
|
+
topic.values_at(:title, :author_name)
|
559
|
+
# => ["Budget", "Jason"]
|
560
|
+
```
|
359
561
|
|
360
|
-
|
562
|
+
Similar to `Hash#values_at` but on an Active Record instance.
|
361
563
|
|
362
|
-
*
|
363
|
-
the parent class was getting deleted when the child was not.
|
564
|
+
*Guillaume Briday*
|
364
565
|
|
365
|
-
|
566
|
+
* Fix `read_attribute_before_type_cast` to consider attribute aliases.
|
366
567
|
|
367
|
-
*
|
568
|
+
*Marcelo Lauxen*
|
368
569
|
|
369
|
-
*
|
570
|
+
* Support passing record to uniqueness validator `:conditions` callable:
|
370
571
|
|
371
|
-
|
572
|
+
```ruby
|
573
|
+
class Article < ApplicationRecord
|
574
|
+
validates_uniqueness_of :title, conditions: ->(article) {
|
575
|
+
published_at = article.published_at
|
576
|
+
where(published_at: published_at.beginning_of_year..published_at.end_of_year)
|
577
|
+
}
|
578
|
+
end
|
579
|
+
```
|
372
580
|
|
373
|
-
*
|
581
|
+
*Eliot Sykes*
|
374
582
|
|
375
|
-
|
583
|
+
* `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
|
584
|
+
total number of rows affected, just like their non-batched counterparts.
|
376
585
|
|
377
|
-
|
378
|
-
|
379
|
-
|
586
|
+
```ruby
|
587
|
+
Person.in_batches.update_all("first_name = 'Eugene'") # => 42
|
588
|
+
Person.in_batches.delete_all # => 42
|
589
|
+
```
|
380
590
|
|
381
|
-
Fixes #
|
591
|
+
Fixes #40287.
|
382
592
|
|
383
|
-
*
|
593
|
+
*Eugene Kenny*
|
384
594
|
|
385
|
-
*
|
595
|
+
* Add support for PostgreSQL `interval` data type with conversion to
|
596
|
+
`ActiveSupport::Duration` when loading records from database and
|
597
|
+
serialization to ISO 8601 formatted duration string on save.
|
598
|
+
Add support to define a column in migrations and get it in a schema dump.
|
599
|
+
Optional column precision is supported.
|
386
600
|
|
387
|
-
|
601
|
+
To use this in 6.1, you need to place the next string to your model file:
|
388
602
|
|
389
|
-
|
603
|
+
attribute :duration, :interval
|
604
|
+
|
605
|
+
To keep old behavior until 6.2 is released:
|
390
606
|
|
391
|
-
|
607
|
+
attribute :duration, :string
|
392
608
|
|
393
|
-
|
609
|
+
Example:
|
394
610
|
|
395
|
-
|
396
|
-
|
611
|
+
create_table :events do |t|
|
612
|
+
t.string :name
|
613
|
+
t.interval :duration
|
614
|
+
end
|
397
615
|
|
398
|
-
|
616
|
+
class Event < ApplicationRecord
|
617
|
+
attribute :duration, :interval
|
618
|
+
end
|
399
619
|
|
400
|
-
|
620
|
+
Event.create!(name: 'Rock Fest', duration: 2.days)
|
621
|
+
Event.last.duration # => 2 days
|
622
|
+
Event.last.duration.iso8601 # => "P2D"
|
623
|
+
Event.new(duration: 'P1DT12H3S').duration # => 1 day, 12 hours, and 3 seconds
|
624
|
+
Event.new(duration: '1 day') # Unknown value will be ignored and NULL will be written to database
|
401
625
|
|
402
|
-
|
403
|
-
|
404
|
-
|
626
|
+
*Andrey Novikov*
|
627
|
+
|
628
|
+
* Allow associations supporting the `dependent:` key to take `dependent: :destroy_async`.
|
405
629
|
|
406
|
-
|
407
|
-
|
630
|
+
```ruby
|
631
|
+
class Account < ActiveRecord::Base
|
632
|
+
belongs_to :supplier, dependent: :destroy_async
|
633
|
+
end
|
408
634
|
```
|
409
635
|
|
410
|
-
|
636
|
+
`:destroy_async` will enqueue a job to destroy associated records in the background.
|
411
637
|
|
412
|
-
*
|
638
|
+
*DHH*, *George Claghorn*, *Cory Gwin*, *Rafael Mendonça França*, *Adrianna Chang*
|
413
639
|
|
414
|
-
*
|
640
|
+
* Add `SKIP_TEST_DATABASE` environment variable to disable modifying the test database when `rails db:create` and `rails db:drop` are called.
|
415
641
|
|
416
|
-
|
642
|
+
*Jason Schweier*
|
417
643
|
|
418
|
-
|
644
|
+
* `connects_to` can only be called on `ActiveRecord::Base` or abstract classes.
|
419
645
|
|
420
|
-
|
646
|
+
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.
|
421
647
|
|
422
|
-
|
648
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
423
649
|
|
424
|
-
|
650
|
+
* All connection adapters `execute` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
651
|
+
`ActiveRecord::StatementInvalid` when they encounter a connection error.
|
425
652
|
|
426
|
-
*
|
653
|
+
*Jean Boussier*
|
427
654
|
|
428
|
-
|
655
|
+
* `Mysql2Adapter#quote_string` now raises `ActiveRecord::ConnectionNotEstablished` rather than
|
656
|
+
`ActiveRecord::StatementInvalid` when it can't connect to the MySQL server.
|
429
657
|
|
430
|
-
*
|
658
|
+
*Jean Boussier*
|
431
659
|
|
432
|
-
|
660
|
+
* Add support for check constraints that are `NOT VALID` via `validate: false` (PostgreSQL-only).
|
433
661
|
|
434
|
-
*
|
662
|
+
*Alex Robbin*
|
435
663
|
|
436
|
-
|
664
|
+
* Ensure the default configuration is considered primary or first for an environment
|
437
665
|
|
438
|
-
|
666
|
+
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.
|
439
667
|
|
440
|
-
|
668
|
+
*Eileen M. Uchitelle*
|
669
|
+
|
670
|
+
* Allow `where` references association names as joined table name aliases.
|
671
|
+
|
672
|
+
```ruby
|
673
|
+
class Comment < ActiveRecord::Base
|
674
|
+
enum label: [:default, :child]
|
675
|
+
has_many :children, class_name: "Comment", foreign_key: :parent_id
|
676
|
+
end
|
441
677
|
|
442
|
-
|
678
|
+
# ... FROM comments LEFT OUTER JOIN comments children ON ... WHERE children.label = 1
|
679
|
+
Comment.includes(:children).where("children.label": "child")
|
680
|
+
```
|
443
681
|
|
444
|
-
*
|
682
|
+
*Ryuta Kamizono*
|
445
683
|
|
446
|
-
|
684
|
+
* Support storing demodulized class name for polymorphic type.
|
447
685
|
|
448
|
-
|
449
|
-
|
450
|
-
has_many :books, through: :author
|
451
|
-
has_many :subscriptions, through: :books
|
452
|
-
end
|
686
|
+
Before Rails 6.1, storing demodulized class name is supported only for STI type
|
687
|
+
by `store_full_sti_class` class attribute.
|
453
688
|
|
454
|
-
|
455
|
-
has_one :post
|
456
|
-
has_many :books
|
457
|
-
has_many :subscriptions, through: :books
|
458
|
-
end
|
689
|
+
Now `store_full_class_name` class attribute can handle both STI and polymorphic types.
|
459
690
|
|
460
|
-
|
461
|
-
belongs_to :author
|
462
|
-
has_many :subscriptions
|
463
|
-
end
|
691
|
+
*Ryuta Kamizono*
|
464
692
|
|
465
|
-
|
466
|
-
|
467
|
-
|
693
|
+
* Deprecate `rails db:structure:{load, dump}` tasks and extend
|
694
|
+
`rails db:schema:{load, dump}` tasks to work with either `:ruby` or `:sql` format,
|
695
|
+
depending on `config.active_record.schema_format` configuration value.
|
468
696
|
|
469
|
-
|
697
|
+
*fatkodima*
|
470
698
|
|
471
|
-
|
699
|
+
* Respect the `select` values for eager loading.
|
472
700
|
|
473
|
-
|
701
|
+
```ruby
|
702
|
+
post = Post.select("UPPER(title) AS title").first
|
703
|
+
post.title # => "WELCOME TO THE WEBLOG"
|
704
|
+
post.body # => ActiveModel::MissingAttributeError
|
705
|
+
|
706
|
+
# Rails 6.0 (ignore the `select` values)
|
707
|
+
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
708
|
+
post.title # => "Welcome to the weblog"
|
709
|
+
post.body # => "Such a lovely day"
|
710
|
+
|
711
|
+
# Rails 6.1 (respect the `select` values)
|
712
|
+
post = Post.select("UPPER(title) AS title").eager_load(:comments).first
|
713
|
+
post.title # => "WELCOME TO THE WEBLOG"
|
714
|
+
post.body # => ActiveModel::MissingAttributeError
|
715
|
+
```
|
474
716
|
|
475
|
-
|
476
|
-
just like it would if `post` were persisted.
|
717
|
+
*Ryuta Kamizono*
|
477
718
|
|
478
|
-
|
719
|
+
* Allow attribute's default to be configured but keeping its own type.
|
479
720
|
|
480
|
-
|
721
|
+
```ruby
|
722
|
+
class Post < ActiveRecord::Base
|
723
|
+
attribute :written_at, default: -> { Time.now.utc }
|
724
|
+
end
|
481
725
|
|
482
|
-
|
483
|
-
|
484
|
-
with `relation.to_a.first(n)`, and also with the behavior of `last(n)`.
|
726
|
+
# Rails 6.0
|
727
|
+
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
|
485
728
|
|
486
|
-
|
729
|
+
# Rails 6.1
|
730
|
+
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
|
731
|
+
```
|
487
732
|
|
488
|
-
*
|
733
|
+
*Ryuta Kamizono*
|
489
734
|
|
490
|
-
*
|
491
|
-
SQL queries for association counting.
|
735
|
+
* Allow default to be configured for Enum.
|
492
736
|
|
493
|
-
|
737
|
+
```ruby
|
738
|
+
class Book < ActiveRecord::Base
|
739
|
+
enum status: [:proposed, :written, :published], _default: :published
|
740
|
+
end
|
494
741
|
|
495
|
-
|
742
|
+
Book.new.status # => "published"
|
743
|
+
```
|
496
744
|
|
497
|
-
*
|
745
|
+
*Ryuta Kamizono*
|
498
746
|
|
499
|
-
*
|
747
|
+
* Deprecate YAML loading from legacy format older than Rails 5.0.
|
500
748
|
|
501
749
|
*Ryuta Kamizono*
|
502
750
|
|
503
|
-
*
|
751
|
+
* Added the setting `ActiveRecord::Base.immutable_strings_by_default`, which
|
752
|
+
allows you to specify that all string columns should be frozen unless
|
753
|
+
otherwise specified. This will reduce memory pressure for applications which
|
754
|
+
do not generally mutate string properties of Active Record objects.
|
755
|
+
|
756
|
+
*Sean Griffin*, *Ryuta Kamizono*
|
757
|
+
|
758
|
+
* Deprecate `map!` and `collect!` on `ActiveRecord::Result`.
|
504
759
|
|
505
760
|
*Ryuta Kamizono*
|
506
761
|
|
507
|
-
*
|
508
|
-
information.
|
762
|
+
* Support `relation.and` for intersection as Set theory.
|
509
763
|
|
510
|
-
|
764
|
+
```ruby
|
765
|
+
david_and_mary = Author.where(id: [david, mary])
|
766
|
+
mary_and_bob = Author.where(id: [mary, bob])
|
511
767
|
|
512
|
-
|
768
|
+
david_and_mary.merge(mary_and_bob) # => [mary, bob]
|
513
769
|
|
514
|
-
|
515
|
-
|
516
|
-
|
770
|
+
david_and_mary.and(mary_and_bob) # => [mary]
|
771
|
+
david_and_mary.or(mary_and_bob) # => [david, mary, bob]
|
772
|
+
```
|
517
773
|
|
518
|
-
|
519
|
-
recommended for use in the production environment since it relies
|
520
|
-
on Ruby's `Kernel#caller_locations` which is fairly slow.
|
774
|
+
*Ryuta Kamizono*
|
521
775
|
|
522
|
-
|
776
|
+
* Merging conditions on the same column no longer maintain both conditions,
|
777
|
+
and will be consistently replaced by the latter condition in Rails 6.2.
|
778
|
+
To migrate to Rails 6.2's behavior, use `relation.merge(other, rewhere: true)`.
|
523
779
|
|
524
|
-
|
780
|
+
```ruby
|
781
|
+
# Rails 6.1 (IN clause is replaced by merger side equality condition)
|
782
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
525
783
|
|
784
|
+
# Rails 6.1 (both conflict conditions exists, deprecated)
|
785
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
|
786
|
+
|
787
|
+
# Rails 6.1 with rewhere to migrate to Rails 6.2's behavior
|
788
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
|
789
|
+
|
790
|
+
# Rails 6.2 (same behavior with IN clause, mergee side condition is consistently replaced)
|
791
|
+
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
|
792
|
+
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
|
526
793
|
```
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
794
|
+
|
795
|
+
*Ryuta Kamizono*
|
796
|
+
|
797
|
+
* Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case.
|
798
|
+
|
799
|
+
*Peter Fry*
|
800
|
+
|
801
|
+
* Resolve issue with insert_all unique_by option when used with expression index.
|
802
|
+
|
803
|
+
When the `:unique_by` option of `ActiveRecord::Persistence.insert_all` and
|
804
|
+
`ActiveRecord::Persistence.upsert_all` was used with the name of an expression index, an error
|
805
|
+
was raised. Adding a guard around the formatting behavior for the `:unique_by` corrects this.
|
806
|
+
|
807
|
+
Usage:
|
808
|
+
|
809
|
+
```ruby
|
810
|
+
create_table :books, id: :integer, force: true do |t|
|
811
|
+
t.column :name, :string
|
812
|
+
t.index "lower(name)", unique: true
|
533
813
|
end
|
534
814
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
815
|
+
Book.insert_all [{ name: "MyTest" }], unique_by: :index_books_on_lower_name
|
816
|
+
```
|
817
|
+
|
818
|
+
Fixes #39516.
|
819
|
+
|
820
|
+
*Austen Madden*
|
821
|
+
|
822
|
+
* Add basic support for CHECK constraints to database migrations.
|
823
|
+
|
824
|
+
Usage:
|
825
|
+
|
826
|
+
```ruby
|
827
|
+
add_check_constraint :products, "price > 0", name: "price_check"
|
828
|
+
remove_check_constraint :products, name: "price_check"
|
829
|
+
```
|
830
|
+
|
831
|
+
*fatkodima*
|
832
|
+
|
833
|
+
* Add `ActiveRecord::Base.strict_loading_by_default` and `ActiveRecord::Base.strict_loading_by_default=`
|
834
|
+
to enable/disable strict_loading mode by default for a model. The configuration's value is
|
835
|
+
inheritable by subclasses, but they can override that value and it will not impact parent class.
|
836
|
+
|
837
|
+
Usage:
|
838
|
+
|
839
|
+
```ruby
|
840
|
+
class Developer < ApplicationRecord
|
841
|
+
self.strict_loading_by_default = true
|
842
|
+
|
843
|
+
has_many :projects
|
540
844
|
end
|
845
|
+
|
846
|
+
dev = Developer.first
|
847
|
+
dev.projects.first
|
848
|
+
# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
|
541
849
|
```
|
542
850
|
|
851
|
+
*bogdanvlviv*
|
852
|
+
|
853
|
+
* Deprecate passing an Active Record object to `quote`/`type_cast` directly.
|
854
|
+
|
855
|
+
*Ryuta Kamizono*
|
856
|
+
|
857
|
+
* Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic.
|
858
|
+
|
543
859
|
Before:
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0)
|
549
|
-
commit transaction
|
550
|
-
|
551
|
-
comment = Comment.create!(post: post)
|
552
|
-
# => begin transaction
|
553
|
-
INSERT INTO "comments" ("post_id") VALUES (1)
|
554
|
-
|
555
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1,
|
556
|
-
"lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1
|
557
|
-
|
558
|
-
UPDATE "posts" SET "updated_at" = '2017-12-11 21:27:11.398330',
|
559
|
-
"lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0
|
560
|
-
rollback transaction
|
561
|
-
# => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post.
|
562
|
-
|
563
|
-
Comment.take.destroy!
|
564
|
-
# => begin transaction
|
565
|
-
DELETE FROM "comments" WHERE "comments"."id" = 1
|
566
|
-
|
567
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1,
|
568
|
-
"lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1
|
569
|
-
|
570
|
-
UPDATE "posts" SET "updated_at" = '2017-12-11 21:42:47.785901',
|
571
|
-
"lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0
|
572
|
-
rollback transaction
|
573
|
-
# => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post.
|
860
|
+
|
861
|
+
```ruby
|
862
|
+
create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
863
|
+
end
|
574
864
|
```
|
575
865
|
|
576
866
|
After:
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0)
|
582
|
-
commit transaction
|
583
|
-
|
584
|
-
comment = Comment.create!(post: post)
|
585
|
-
# => begin transaction
|
586
|
-
INSERT INTO "comments" ("post_id") VALUES (1)
|
587
|
-
|
588
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1,
|
589
|
-
"lock_version" = COALESCE("lock_version", 0) + 1,
|
590
|
-
"updated_at" = '2017-12-11 21:37:09.802642' WHERE "posts"."id" = 1
|
591
|
-
commit transaction
|
592
|
-
|
593
|
-
comment.destroy!
|
594
|
-
# => begin transaction
|
595
|
-
DELETE FROM "comments" WHERE "comments"."id" = 1
|
596
|
-
|
597
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1,
|
598
|
-
"lock_version" = COALESCE("lock_version", 0) + 1,
|
599
|
-
"updated_at" = '2017-12-11 21:39:02.685520' WHERE "posts"."id" = 1
|
600
|
-
commit transaction
|
867
|
+
|
868
|
+
```ruby
|
869
|
+
create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
870
|
+
end
|
601
871
|
```
|
602
872
|
|
603
|
-
|
873
|
+
*Ryuta Kamizono*
|
604
874
|
|
605
|
-
|
875
|
+
* Added delegated type as an alternative to single-table inheritance for representing class hierarchies.
|
876
|
+
See ActiveRecord::DelegatedType for the full description.
|
606
877
|
|
607
|
-
*
|
878
|
+
*DHH*
|
608
879
|
|
609
|
-
|
880
|
+
* Deprecate aggregations with group by duplicated fields.
|
610
881
|
|
611
|
-
|
882
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:group)` to deduplicate group fields.
|
612
883
|
|
613
|
-
|
884
|
+
```ruby
|
885
|
+
accounts = Account.group(:firm_id)
|
886
|
+
|
887
|
+
# duplicated group fields, deprecated.
|
888
|
+
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
|
889
|
+
# => {
|
890
|
+
# [1, 1] => 50,
|
891
|
+
# [2, 2] => 60
|
892
|
+
# }
|
893
|
+
|
894
|
+
# use `uniq!(:group)` to deduplicate group fields.
|
895
|
+
accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
|
896
|
+
# => {
|
897
|
+
# 1 => 50,
|
898
|
+
# 2 => 60
|
899
|
+
# }
|
900
|
+
```
|
614
901
|
|
615
|
-
*
|
902
|
+
*Ryuta Kamizono*
|
616
903
|
|
617
|
-
|
904
|
+
* Deprecate duplicated query annotations.
|
618
905
|
|
619
|
-
|
906
|
+
To migrate to Rails 6.2's behavior, use `uniq!(:annotate)` to deduplicate query annotations.
|
620
907
|
|
621
|
-
|
622
|
-
|
908
|
+
```ruby
|
909
|
+
accounts = Account.where(id: [1, 2]).annotate("david and mary")
|
910
|
+
|
911
|
+
# duplicated annotations, deprecated.
|
912
|
+
accounts.merge(accounts.rewhere(id: 3))
|
913
|
+
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */ /* david and mary */
|
914
|
+
|
915
|
+
# use `uniq!(:annotate)` to deduplicate annotations.
|
916
|
+
accounts.merge(accounts.rewhere(id: 3)).uniq!(:annotate)
|
917
|
+
# SELECT accounts.* FROM accounts WHERE accounts.id = 3 /* david and mary */
|
918
|
+
```
|
623
919
|
|
624
920
|
*Ryuta Kamizono*
|
625
921
|
|
626
|
-
*
|
627
|
-
migrating up, e.g. populating a new column.
|
922
|
+
* Resolve conflict between counter cache and optimistic locking.
|
628
923
|
|
629
|
-
|
924
|
+
Bump an Active Record instance's lock version after updating its counter
|
925
|
+
cache. This avoids raising an unnecessary `ActiveRecord::StaleObjectError`
|
926
|
+
upon subsequent transactions by maintaining parity with the corresponding
|
927
|
+
database record's `lock_version` column.
|
630
928
|
|
631
|
-
|
632
|
-
relation query methods.
|
929
|
+
Fixes #16449.
|
633
930
|
|
634
|
-
|
635
|
-
|
636
|
-
|
931
|
+
*Aaron Lipman*
|
932
|
+
|
933
|
+
* Support merging option `:rewhere` to allow mergee side condition to be replaced exactly.
|
934
|
+
|
935
|
+
```ruby
|
936
|
+
david_and_mary = Author.where(id: david.id..mary.id)
|
937
|
+
|
938
|
+
# both conflict conditions exists
|
939
|
+
david_and_mary.merge(Author.where(id: bob)) # => []
|
940
|
+
|
941
|
+
# mergee side condition is replaced by rewhere
|
942
|
+
david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]
|
943
|
+
|
944
|
+
# mergee side condition is replaced by rewhere option
|
945
|
+
david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
|
637
946
|
```
|
638
947
|
|
639
|
-
|
948
|
+
*Ryuta Kamizono*
|
949
|
+
|
950
|
+
* Add support for finding records based on signed ids, which are tamper-proof, verified ids that can be
|
951
|
+
set to expire and scoped with a purpose. This is particularly useful for things like password reset
|
952
|
+
or email verification, where you want the bearer of the signed id to be able to interact with the
|
953
|
+
underlying record, but usually only within a certain time period.
|
954
|
+
|
955
|
+
```ruby
|
956
|
+
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
|
957
|
+
|
958
|
+
User.find_signed signed_id # => nil, since the purpose does not match
|
959
|
+
|
960
|
+
travel 16.minutes
|
961
|
+
User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
|
962
|
+
|
963
|
+
travel_back
|
964
|
+
User.find_signed signed_id, purpose: :password_reset # => User.first
|
965
|
+
|
966
|
+
User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
|
640
967
|
```
|
641
|
-
|
968
|
+
|
969
|
+
*DHH*
|
970
|
+
|
971
|
+
* Support `ALGORITHM = INSTANT` DDL option for index operations on MySQL.
|
972
|
+
|
973
|
+
*Ryuta Kamizono*
|
974
|
+
|
975
|
+
* Fix index creation to preserve index comment in bulk change table on MySQL.
|
976
|
+
|
977
|
+
*Ryuta Kamizono*
|
978
|
+
|
979
|
+
* Allow `unscope` to be aware of table name qualified values.
|
980
|
+
|
981
|
+
It is possible to unscope only the column in the specified table.
|
982
|
+
|
983
|
+
```ruby
|
984
|
+
posts = Post.joins(:comments).group(:"posts.hidden")
|
985
|
+
posts = posts.where("posts.hidden": false, "comments.hidden": false)
|
986
|
+
|
987
|
+
posts.count
|
988
|
+
# => { false => 10 }
|
989
|
+
|
990
|
+
# unscope both hidden columns
|
991
|
+
posts.unscope(where: :hidden).count
|
992
|
+
# => { false => 11, true => 1 }
|
993
|
+
|
994
|
+
# unscope only comments.hidden column
|
995
|
+
posts.unscope(where: :"comments.hidden").count
|
996
|
+
# => { false => 11 }
|
642
997
|
```
|
643
998
|
|
644
|
-
|
645
|
-
|
646
|
-
|
999
|
+
*Ryuta Kamizono*, *Slava Korolev*
|
1000
|
+
|
1001
|
+
* Fix `rewhere` to truly overwrite collided where clause by new where clause.
|
1002
|
+
|
1003
|
+
```ruby
|
1004
|
+
steve = Person.find_by(name: "Steve")
|
1005
|
+
david = Author.find_by(name: "David")
|
1006
|
+
|
1007
|
+
relation = Essay.where(writer: steve)
|
647
1008
|
|
648
|
-
|
649
|
-
|
650
|
-
can opt in to the future behavior by setting `allow_unsafe_raw_sql`
|
651
|
-
to `:disabled`.
|
1009
|
+
# Before
|
1010
|
+
relation.rewhere(writer: david).to_a # => []
|
652
1011
|
|
653
|
-
|
654
|
-
|
1012
|
+
# After
|
1013
|
+
relation.rewhere(writer: david).to_a # => [david]
|
655
1014
|
```
|
656
|
-
|
1015
|
+
|
1016
|
+
*Ryuta Kamizono*
|
1017
|
+
|
1018
|
+
* Inspect time attributes with subsec and time zone offset.
|
1019
|
+
|
1020
|
+
```ruby
|
1021
|
+
p Knot.create
|
1022
|
+
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000 +0000">
|
657
1023
|
```
|
658
1024
|
|
659
|
-
*
|
1025
|
+
*akinomaeni*, *Jonathan Hefner*
|
660
1026
|
|
661
|
-
*
|
662
|
-
`Type#serialize`. This means that `update_all(foo: 'true')` will properly
|
663
|
-
persist a boolean.
|
1027
|
+
* Deprecate passing a column to `type_cast`.
|
664
1028
|
|
665
|
-
*
|
1029
|
+
*Ryuta Kamizono*
|
666
1030
|
|
667
|
-
*
|
668
|
-
when statement timeout exceeded.
|
1031
|
+
* Deprecate `in_clause_length` and `allowed_index_name_length` in `DatabaseLimits`.
|
669
1032
|
|
670
1033
|
*Ryuta Kamizono*
|
671
1034
|
|
672
|
-
*
|
673
|
-
`bin/rails db:migrate` with empty VERSION behaves as without `VERSION`.
|
674
|
-
Check a format of `VERSION`: Allow a migration version number
|
675
|
-
or name of a migration file. Raise error if format of `VERSION` is invalid.
|
676
|
-
Raise error if target migration doesn't exist.
|
1035
|
+
* Support bulk insert/upsert on relation to preserve scope values.
|
677
1036
|
|
678
|
-
*
|
1037
|
+
*Josef Šimánek*, *Ryuta Kamizono*
|
679
1038
|
|
680
|
-
*
|
681
|
-
`db/schema.rb` when using the sqlite adapter.
|
1039
|
+
* Preserve column comment value on changing column name on MySQL.
|
682
1040
|
|
683
|
-
|
1041
|
+
*Islam Taha*
|
684
1042
|
|
685
|
-
|
1043
|
+
* Add support for `if_exists` option for removing an index.
|
686
1044
|
|
687
|
-
|
1045
|
+
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.
|
688
1046
|
|
689
|
-
*
|
1047
|
+
*Eileen M. Uchitelle*
|
690
1048
|
|
691
|
-
* Remove
|
1049
|
+
* Remove ibm_db, informix, mssql, oracle, and oracle12 Arel visitors which are not used in the code base.
|
692
1050
|
|
693
|
-
*
|
1051
|
+
*Ryuta Kamizono*
|
694
1052
|
|
695
|
-
*
|
1053
|
+
* Prevent `build_association` from `touching` a parent record if the record isn't persisted for `has_one` associations.
|
696
1054
|
|
697
|
-
|
1055
|
+
Fixes #38219.
|
698
1056
|
|
699
|
-
*
|
1057
|
+
*Josh Brody*
|
700
1058
|
|
701
|
-
|
1059
|
+
* Add support for `if_not_exists` option for adding index.
|
702
1060
|
|
703
|
-
|
1061
|
+
The `add_index` method respects `if_not_exists` option. If it is set to true
|
1062
|
+
index won't be added.
|
704
1063
|
|
705
|
-
|
1064
|
+
Usage:
|
706
1065
|
|
707
|
-
|
1066
|
+
```ruby
|
1067
|
+
add_index :users, :account_id, if_not_exists: true
|
1068
|
+
```
|
708
1069
|
|
709
|
-
|
1070
|
+
The `if_not_exists` option passed to `create_table` also gets propagated to indexes
|
1071
|
+
created within that migration so that if table and its indexes exist then there is no
|
1072
|
+
attempt to create them again.
|
710
1073
|
|
711
|
-
*
|
1074
|
+
*Prathamesh Sonpatki*
|
712
1075
|
|
713
|
-
|
1076
|
+
* Add `ActiveRecord::Base#previously_new_record?` to show if a record was new before the last save.
|
714
1077
|
|
715
|
-
*
|
1078
|
+
*Tom Ward*
|
716
1079
|
|
717
|
-
|
1080
|
+
* Support descending order for `find_each`, `find_in_batches`, and `in_batches`.
|
718
1081
|
|
719
|
-
|
1082
|
+
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.
|
720
1083
|
|
721
|
-
|
1084
|
+
This change allows reversing the order, batching from newest to oldest. This is useful when you need to process newer batches of records first.
|
722
1085
|
|
723
|
-
|
1086
|
+
Pass `order: :desc` to yield batches in descending order. The default remains `order: :asc`.
|
724
1087
|
|
725
|
-
|
1088
|
+
```ruby
|
1089
|
+
Person.find_each(order: :desc) do |person|
|
1090
|
+
person.party_all_night!
|
1091
|
+
end
|
1092
|
+
```
|
726
1093
|
|
727
|
-
*
|
1094
|
+
*Alexey Vasiliev*
|
728
1095
|
|
729
|
-
|
1096
|
+
* Fix `insert_all` with enum values.
|
730
1097
|
|
731
|
-
|
1098
|
+
Fixes #38716.
|
732
1099
|
|
733
|
-
*
|
1100
|
+
*Joel Blum*
|
734
1101
|
|
735
|
-
*
|
1102
|
+
* Add support for `db:rollback:name` for multiple database applications.
|
736
1103
|
|
737
|
-
|
1104
|
+
Multiple database applications will now raise if `db:rollback` is call and recommend using the `db:rollback:[NAME]` to rollback migrations.
|
738
1105
|
|
739
|
-
*
|
740
|
-
ar_internal_metadata's data for a test database.
|
1106
|
+
*Eileen M. Uchitelle*
|
741
1107
|
|
742
|
-
|
1108
|
+
* `Relation#pick` now uses already loaded results instead of making another query.
|
1109
|
+
|
1110
|
+
*Eugene Kenny*
|
1111
|
+
|
1112
|
+
* Deprecate using `return`, `break` or `throw` to exit a transaction block after writes.
|
1113
|
+
|
1114
|
+
*Dylan Thacker-Smith*
|
1115
|
+
|
1116
|
+
* Dump the schema or structure of a database when calling `db:migrate:name`.
|
1117
|
+
|
1118
|
+
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.
|
1119
|
+
|
1120
|
+
Going forward, calls to `rails db:migrate:name` will dump the schema (or structure) of the database being migrated.
|
1121
|
+
|
1122
|
+
*Kyle Thompson*
|
1123
|
+
|
1124
|
+
* Reset the `ActiveRecord::Base` connection after `rails db:migrate:name`.
|
1125
|
+
|
1126
|
+
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.
|
1127
|
+
|
1128
|
+
*Kyle Thompson*
|
1129
|
+
|
1130
|
+
* Disallow calling `connected_to` on subclasses of `ActiveRecord::Base`.
|
1131
|
+
|
1132
|
+
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.
|
1133
|
+
|
1134
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1135
|
+
|
1136
|
+
* Add support for horizontal sharding to `connects_to` and `connected_to`.
|
1137
|
+
|
1138
|
+
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.
|
1139
|
+
|
1140
|
+
Usage:
|
1141
|
+
|
1142
|
+
Given the following configuration:
|
1143
|
+
|
1144
|
+
```yaml
|
1145
|
+
# config/database.yml
|
1146
|
+
production:
|
1147
|
+
primary:
|
1148
|
+
database: my_database
|
1149
|
+
primary_shard_one:
|
1150
|
+
database: my_database_shard_one
|
743
1151
|
```
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
1152
|
+
|
1153
|
+
Connect to multiple shards:
|
1154
|
+
|
1155
|
+
```ruby
|
1156
|
+
class ApplicationRecord < ActiveRecord::Base
|
1157
|
+
self.abstract_class = true
|
1158
|
+
|
1159
|
+
connects_to shards: {
|
1160
|
+
default: { writing: :primary },
|
1161
|
+
shard_one: { writing: :primary_shard_one }
|
1162
|
+
}
|
748
1163
|
```
|
749
1164
|
|
750
|
-
|
1165
|
+
Swap between shards in your controller / model code:
|
1166
|
+
|
1167
|
+
```ruby
|
1168
|
+
ActiveRecord::Base.connected_to(shard: :shard_one) do
|
1169
|
+
# Read from shard one
|
1170
|
+
end
|
751
1171
|
```
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
1172
|
+
|
1173
|
+
The horizontal sharding API also supports read replicas. See guides for more details.
|
1174
|
+
|
1175
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1176
|
+
|
1177
|
+
* Deprecate `spec_name` in favor of `name` on database configurations.
|
1178
|
+
|
1179
|
+
The accessors for `spec_name` on `configs_for` and `DatabaseConfig` are deprecated. Please use `name` instead.
|
1180
|
+
|
1181
|
+
Deprecated behavior:
|
1182
|
+
|
1183
|
+
```ruby
|
1184
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
|
1185
|
+
db_config.spec_name
|
756
1186
|
```
|
757
1187
|
|
758
|
-
|
1188
|
+
New behavior:
|
759
1189
|
|
760
|
-
|
1190
|
+
```ruby
|
1191
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary")
|
1192
|
+
db_config.name
|
1193
|
+
```
|
761
1194
|
|
762
|
-
*
|
1195
|
+
*Eileen M. Uchitelle*
|
763
1196
|
|
764
|
-
|
1197
|
+
* Add additional database-specific rake tasks for multi-database users.
|
765
1198
|
|
766
|
-
|
1199
|
+
Previously, `rails db:create`, `rails db:drop`, and `rails db:migrate` were the only rails tasks that could operate on a single
|
1200
|
+
database. For example:
|
767
1201
|
|
768
|
-
|
1202
|
+
```
|
1203
|
+
rails db:create
|
1204
|
+
rails db:create:primary
|
1205
|
+
rails db:create:animals
|
1206
|
+
rails db:drop
|
1207
|
+
rails db:drop:primary
|
1208
|
+
rails db:drop:animals
|
1209
|
+
rails db:migrate
|
1210
|
+
rails db:migrate:primary
|
1211
|
+
rails db:migrate:animals
|
1212
|
+
```
|
769
1213
|
|
770
|
-
|
1214
|
+
With these changes, `rails db:schema:dump`, `rails db:schema:load`, `rails db:structure:dump`, `rails db:structure:load` and
|
1215
|
+
`rails db:test:prepare` can additionally operate on a single database. For example:
|
771
1216
|
|
772
|
-
|
1217
|
+
```
|
1218
|
+
rails db:schema:dump
|
1219
|
+
rails db:schema:dump:primary
|
1220
|
+
rails db:schema:dump:animals
|
1221
|
+
rails db:schema:load
|
1222
|
+
rails db:schema:load:primary
|
1223
|
+
rails db:schema:load:animals
|
1224
|
+
rails db:structure:dump
|
1225
|
+
rails db:structure:dump:primary
|
1226
|
+
rails db:structure:dump:animals
|
1227
|
+
rails db:structure:load
|
1228
|
+
rails db:structure:load:primary
|
1229
|
+
rails db:structure:load:animals
|
1230
|
+
rails db:test:prepare
|
1231
|
+
rails db:test:prepare:primary
|
1232
|
+
rails db:test:prepare:animals
|
1233
|
+
```
|
773
1234
|
|
774
|
-
*
|
1235
|
+
*Kyle Thompson*
|
775
1236
|
|
776
|
-
|
1237
|
+
* Add support for `strict_loading` mode on association declarations.
|
777
1238
|
|
778
|
-
|
1239
|
+
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.
|
779
1240
|
|
780
|
-
|
1241
|
+
Usage:
|
781
1242
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
dropped in SQL commands:
|
1243
|
+
```ruby
|
1244
|
+
class Developer < ApplicationRecord
|
1245
|
+
has_many :projects, strict_loading: true
|
1246
|
+
end
|
787
1247
|
|
788
|
-
|
1248
|
+
dev = Developer.first
|
1249
|
+
dev.projects.first
|
1250
|
+
# => ActiveRecord::StrictLoadingViolationError: The projects association is marked as strict_loading and cannot be lazily loaded.
|
1251
|
+
```
|
789
1252
|
|
790
|
-
|
791
|
-
# => "[2010-01-01 13:30:00 UTC,2011-02-02 19:30:00 UTC)"
|
1253
|
+
*Kevin Deisz*
|
792
1254
|
|
793
|
-
|
1255
|
+
* Add support for `strict_loading` mode to prevent lazy loading of records.
|
794
1256
|
|
795
|
-
|
796
|
-
# => "[2010-01-01 13:30:00.670277,2011-02-02 19:30:00.745125)"
|
1257
|
+
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.
|
797
1258
|
|
798
|
-
|
1259
|
+
Usage:
|
799
1260
|
|
800
|
-
|
801
|
-
|
1261
|
+
```ruby
|
1262
|
+
dev = Developer.strict_loading.first
|
1263
|
+
dev.audit_logs.to_a
|
1264
|
+
# => ActiveRecord::StrictLoadingViolationError: Developer is marked as strict_loading and AuditLog cannot be lazily loaded.
|
1265
|
+
```
|
802
1266
|
|
803
|
-
*
|
1267
|
+
*Eileen M. Uchitelle*, *Aaron Patterson*
|
804
1268
|
|
805
|
-
*
|
1269
|
+
* Add support for PostgreSQL 11+ partitioned indexes when using `upsert_all`.
|
806
1270
|
|
807
|
-
|
1271
|
+
*Sebastián Palma*
|
808
1272
|
|
809
|
-
|
1273
|
+
* Adds support for `if_not_exists` to `add_column` and `if_exists` to `remove_column`.
|
810
1274
|
|
811
|
-
|
812
|
-
more descriptive.
|
1275
|
+
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.
|
813
1276
|
|
814
|
-
|
1277
|
+
Example Usage:
|
815
1278
|
|
816
|
-
|
1279
|
+
```ruby
|
1280
|
+
class AddColumnTitle < ActiveRecord::Migration[6.1]
|
1281
|
+
def change
|
1282
|
+
add_column :posts, :title, :string, if_not_exists: true
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
```
|
817
1286
|
|
818
|
-
|
819
|
-
|
1287
|
+
```ruby
|
1288
|
+
class RemoveColumnTitle < ActiveRecord::Migration[6.1]
|
1289
|
+
def change
|
1290
|
+
remove_column :posts, :title, if_exists: true
|
1291
|
+
end
|
1292
|
+
end
|
1293
|
+
```
|
820
1294
|
|
821
|
-
*
|
1295
|
+
*Eileen M. Uchitelle*
|
822
1296
|
|
823
|
-
*
|
1297
|
+
* Regexp-escape table name for MS SQL Server.
|
824
1298
|
|
825
|
-
|
1299
|
+
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.
|
826
1300
|
|
827
|
-
*
|
1301
|
+
*Larry Reid*
|
828
1302
|
|
829
|
-
|
1303
|
+
* Store advisory locks on their own named connection.
|
830
1304
|
|
831
|
-
|
1305
|
+
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.
|
832
1306
|
|
833
|
-
|
1307
|
+
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.
|
834
1308
|
|
835
|
-
*
|
1309
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
836
1310
|
|
837
|
-
*
|
1311
|
+
* Allow schema cache path to be defined in the database configuration file.
|
838
1312
|
|
839
|
-
|
1313
|
+
For example:
|
840
1314
|
|
841
|
-
|
1315
|
+
```yaml
|
1316
|
+
development:
|
1317
|
+
adapter: postgresql
|
1318
|
+
database: blog_development
|
1319
|
+
pool: 5
|
1320
|
+
schema_cache_path: tmp/schema/main.yml
|
1321
|
+
```
|
842
1322
|
|
843
|
-
*
|
1323
|
+
*Katrina Owen*
|
844
1324
|
|
845
|
-
* `
|
846
|
-
`references` only, as `references` can be implicitly called by `where`.
|
1325
|
+
* Deprecate `#remove_connection` in favor of `#remove_connection_pool` when called on the handler.
|
847
1326
|
|
848
|
-
|
1327
|
+
`#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.
|
849
1328
|
|
850
|
-
*
|
1329
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
851
1330
|
|
852
|
-
* `
|
853
|
-
need to generate it, it can be created with `rails g application_record`.
|
1331
|
+
* Deprecate `#default_hash` and it's alias `#[]` on database configurations.
|
854
1332
|
|
855
|
-
|
1333
|
+
Applications should use `configs_for`. `#default_hash` and `#[]` will be removed in 6.2.
|
856
1334
|
|
857
|
-
*
|
1335
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
858
1336
|
|
859
|
-
|
1337
|
+
* Add scale support to `ActiveRecord::Validations::NumericalityValidator`.
|
860
1338
|
|
861
|
-
*
|
862
|
-
`destroyed_by_association` will now be set to the reflection, matching the
|
863
|
-
behaviour of `has_many` associations.
|
1339
|
+
*Gannon McGibbon*
|
864
1340
|
|
865
|
-
|
1341
|
+
* Find orphans by looking for missing relations through chaining `where.missing`:
|
866
1342
|
|
867
|
-
|
1343
|
+
Before:
|
868
1344
|
|
869
|
-
|
870
|
-
|
1345
|
+
```ruby
|
1346
|
+
Post.left_joins(:author).where(authors: { id: nil })
|
1347
|
+
```
|
871
1348
|
|
1349
|
+
After:
|
1350
|
+
|
1351
|
+
```ruby
|
1352
|
+
Post.where.missing(:author)
|
872
1353
|
```
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
1354
|
+
|
1355
|
+
*Tom Rossi*
|
1356
|
+
|
1357
|
+
* Ensure `:reading` connections always raise if a write is attempted.
|
1358
|
+
|
1359
|
+
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`.
|
1360
|
+
|
1361
|
+
*Eileen M. Uchitelle*
|
1362
|
+
|
1363
|
+
* Deprecate `"primary"` as the `connection_specification_name` for `ActiveRecord::Base`.
|
1364
|
+
|
1365
|
+
`"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"`.
|
1366
|
+
|
1367
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
1368
|
+
|
1369
|
+
* Add `ActiveRecord::Validations::NumericalityValidator` with
|
1370
|
+
support for casting floats using a database columns' precision value.
|
1371
|
+
|
1372
|
+
*Gannon McGibbon*
|
1373
|
+
|
1374
|
+
* Enforce fresh ETag header after a collection's contents change by adding
|
1375
|
+
ActiveRecord::Relation#cache_key_with_version. This method will be used by
|
1376
|
+
ActionController::ConditionalGet to ensure that when collection cache versioning
|
1377
|
+
is enabled, requests using ConditionalGet don't return the same ETag header
|
1378
|
+
after a collection is modified.
|
1379
|
+
|
1380
|
+
Fixes #38078.
|
1381
|
+
|
1382
|
+
*Aaron Lipman*
|
1383
|
+
|
1384
|
+
* Skip test database when running `db:create` or `db:drop` in development
|
1385
|
+
with `DATABASE_URL` set.
|
1386
|
+
|
1387
|
+
*Brian Buchalter*
|
1388
|
+
|
1389
|
+
* Don't allow mutations on the database configurations hash.
|
1390
|
+
|
1391
|
+
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.
|
1392
|
+
|
1393
|
+
Before:
|
1394
|
+
|
1395
|
+
```ruby
|
1396
|
+
@db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
|
1397
|
+
@db_config.configuration_hash.merge!(idle_timeout: "0.02")
|
878
1398
|
```
|
879
1399
|
|
880
|
-
|
1400
|
+
After:
|
881
1401
|
|
882
|
-
|
883
|
-
|
1402
|
+
```ruby
|
1403
|
+
@db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", spec_name: "primary")
|
1404
|
+
config = @db_config.configuration_hash.merge(idle_timeout: "0.02")
|
1405
|
+
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.spec_name, config)
|
1406
|
+
```
|
884
1407
|
|
885
|
-
*
|
1408
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
886
1409
|
|
887
|
-
* `
|
888
|
-
`current_scope`, with the exception of `unscoped`.
|
1410
|
+
* Remove `:connection_id` from the `sql.active_record` notification.
|
889
1411
|
|
890
|
-
|
1412
|
+
*Aaron Patterson*, *Rafael Mendonça França*
|
891
1413
|
|
892
|
-
|
1414
|
+
* The `:name` key will no longer be returned as part of `DatabaseConfig#configuration_hash`. Please use `DatabaseConfig#owner_name` instead.
|
893
1415
|
|
894
|
-
*
|
1416
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
895
1417
|
|
896
|
-
|
897
|
-
recognize 't' and 'f' as was previously serialized.
|
1418
|
+
* ActiveRecord's `belongs_to_required_by_default` flag can now be set per model.
|
898
1419
|
|
899
|
-
|
900
|
-
|
901
|
-
whose default false value is deprecated.
|
1420
|
+
You can now opt-out/opt-in specific models from having their associations required
|
1421
|
+
by default.
|
902
1422
|
|
903
|
-
|
1423
|
+
This change is meant to ease the process of migrating all your models to have
|
1424
|
+
their association required.
|
904
1425
|
|
905
|
-
*
|
906
|
-
`in_batches`).
|
1426
|
+
*Edouard Chin*
|
907
1427
|
|
908
|
-
|
909
|
-
until the end of the request or job.
|
1428
|
+
* The `connection_config` method has been deprecated, please use `connection_db_config` instead which will return a `DatabaseConfigurations::DatabaseConfig` instead of a `Hash`.
|
910
1429
|
|
911
|
-
*
|
1430
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
912
1431
|
|
913
|
-
*
|
914
|
-
`ActiveRecord::StatementInvalid` exceptions.
|
1432
|
+
* Retain explicit selections on the base model after applying `includes` and `joins`.
|
915
1433
|
|
916
|
-
|
1434
|
+
Resolves #34889.
|
917
1435
|
|
918
|
-
*
|
1436
|
+
*Patrick Rebsch*
|
919
1437
|
|
920
|
-
|
1438
|
+
* 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.
|
921
1439
|
|
922
|
-
*
|
1440
|
+
*Eileen M. Uchitelle*, *John Crepezzi*
|
923
1441
|
|
924
|
-
*
|
1442
|
+
* Allow attributes to be fetched from Arel node groupings.
|
925
1443
|
|
926
|
-
|
927
|
-
inner transaction would still be marked as persisted.
|
1444
|
+
*Jeff Emminger*, *Gannon McGibbon*
|
928
1445
|
|
929
|
-
|
930
|
-
parent transaction is rolledback. This will correctly mark records from the inner transaction as not persisted.
|
1446
|
+
* A database URL can now contain a querystring value that contains an equal sign. This is needed to support passing PostgreSQL `options`.
|
931
1447
|
|
932
|
-
*
|
1448
|
+
*Joshua Flanagan*
|
933
1449
|
|
934
|
-
*
|
1450
|
+
* 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`.
|
935
1451
|
|
936
|
-
|
937
|
-
state of the transaction you can now use `rollback!`, `commit!` or `nullify!` instead of
|
938
|
-
`set_state(:rolledback)`, `set_state(:committed)`, or `set_state(nil)`.
|
1452
|
+
*John Crepezzi*
|
939
1453
|
|
940
|
-
|
1454
|
+
* Specifying `implicit_order_column` now subsorts the records by primary key if available to ensure deterministic results.
|
941
1455
|
|
942
|
-
*
|
1456
|
+
*Paweł Urbanek*
|
943
1457
|
|
944
|
-
|
1458
|
+
* `where(attr => [])` now loads an empty result without making a query.
|
945
1459
|
|
946
|
-
*
|
947
|
-
without being connected.
|
1460
|
+
*John Hawthorn*
|
948
1461
|
|
949
|
-
|
1462
|
+
* Fixed the performance regression for `primary_keys` introduced MySQL 8.0.
|
950
1463
|
|
951
|
-
*
|
952
|
-
if the child records were deleted before the parent was saved, they would
|
953
|
-
still be persisted. Now, if child records are deleted before the parent is saved
|
954
|
-
on a `has_many :through` association, the child records will not be persisted.
|
1464
|
+
*Hiroyuki Ishii*
|
955
1465
|
|
956
|
-
|
1466
|
+
* Add support for `belongs_to` to `has_many` inversing.
|
957
1467
|
|
958
|
-
*
|
959
|
-
the merged relation into LEFT OUTER JOIN.
|
1468
|
+
*Gannon McGibbon*
|
960
1469
|
|
961
|
-
|
1470
|
+
* Allow length configuration for `has_secure_token` method. The minimum length
|
1471
|
+
is set at 24 characters.
|
962
1472
|
|
1473
|
+
Before:
|
1474
|
+
|
1475
|
+
```ruby
|
1476
|
+
has_secure_token :auth_token
|
963
1477
|
```
|
964
|
-
Author.joins(:posts).merge(Post.joins(:comments))
|
965
|
-
# Before the change:
|
966
|
-
#=> SELECT ... FROM authors INNER JOIN posts ON ... LEFT OUTER JOIN comments ON...
|
967
1478
|
|
968
|
-
|
969
|
-
|
1479
|
+
After:
|
1480
|
+
|
1481
|
+
```ruby
|
1482
|
+
has_secure_token :default_token # 24 characters
|
1483
|
+
has_secure_token :auth_token, length: 36 # 36 characters
|
1484
|
+
has_secure_token :invalid_token, length: 12 # => ActiveRecord::SecureToken::MinimumLengthError
|
970
1485
|
```
|
971
1486
|
|
972
|
-
*
|
1487
|
+
*Bernardo de Araujo*
|
973
1488
|
|
974
|
-
* `
|
975
|
-
`locking_column`, without default value, is null in the database.
|
1489
|
+
* Deprecate `DatabaseConfigurations#to_h`. These connection hashes are still available via `ActiveRecord::Base.configurations.configs_for`.
|
976
1490
|
|
977
|
-
*
|
1491
|
+
*Eileen Uchitelle*, *John Crepezzi*
|
978
1492
|
|
979
|
-
*
|
980
|
-
`locking_column` is null in the database.
|
1493
|
+
* 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.
|
981
1494
|
|
982
|
-
*
|
1495
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
1496
|
+
|
1497
|
+
* Allow column names to be passed to `remove_index` positionally along with other options.
|
1498
|
+
|
1499
|
+
Passing other options can be necessary to make `remove_index` correctly reversible.
|
1500
|
+
|
1501
|
+
Before:
|
983
1502
|
|
984
|
-
|
1503
|
+
add_index :reports, :report_id # => works
|
1504
|
+
add_index :reports, :report_id, unique: true # => works
|
1505
|
+
remove_index :reports, :report_id # => works
|
1506
|
+
remove_index :reports, :report_id, unique: true # => ArgumentError
|
1507
|
+
|
1508
|
+
After:
|
1509
|
+
|
1510
|
+
remove_index :reports, :report_id, unique: true # => works
|
1511
|
+
|
1512
|
+
*Eugene Kenny*
|
1513
|
+
|
1514
|
+
* Allow bulk `ALTER` statements to drop and recreate indexes with the same name.
|
1515
|
+
|
1516
|
+
*Eugene Kenny*
|
1517
|
+
|
1518
|
+
* `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
|
1519
|
+
|
1520
|
+
*Eugene Kenny*
|
1521
|
+
|
1522
|
+
* Call `while_preventing_writes` directly from `connected_to`.
|
1523
|
+
|
1524
|
+
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)`.
|
1525
|
+
|
1526
|
+
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.
|
1527
|
+
|
1528
|
+
*Eileen M. Uchitelle*
|
1529
|
+
|
1530
|
+
* Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter in the edge case when the query is terminated during filesort.
|
985
1531
|
|
986
1532
|
*Kir Shatrov*
|
987
1533
|
|
988
|
-
*
|
1534
|
+
* Stop trying to read yaml file fixtures when loading Active Record fixtures.
|
1535
|
+
|
1536
|
+
*Gannon McGibbon*
|
1537
|
+
|
1538
|
+
* Deprecate `.reorder(nil)` with `.first` / `.first!` taking non-deterministic result.
|
1539
|
+
|
1540
|
+
To continue taking non-deterministic result, use `.take` / `.take!` instead.
|
989
1541
|
|
990
1542
|
*Ryuta Kamizono*
|
991
1543
|
|
992
|
-
*
|
1544
|
+
* Preserve user supplied joins order as much as possible.
|
1545
|
+
|
1546
|
+
Fixes #36761, #34328, #24281, #12953.
|
993
1547
|
|
994
1548
|
*Ryuta Kamizono*
|
995
1549
|
|
996
|
-
*
|
1550
|
+
* Allow `matches_regex` and `does_not_match_regexp` on the MySQL Arel visitor.
|
997
1551
|
|
998
|
-
|
1552
|
+
*James Pearson*
|
999
1553
|
|
1000
|
-
|
1554
|
+
* Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section.
|
1001
1555
|
|
1002
|
-
*
|
1003
|
-
in `ActiveSupport::Cache`. This also means that `ActiveRecord::Base#cache_key` will now return a stable key
|
1004
|
-
that does not include a timestamp any more.
|
1556
|
+
*Tongfei Gao*
|
1005
1557
|
|
1006
|
-
|
1007
|
-
until you set `ActiveRecord::Base.cache_versioning = true`. That's the setting for all new apps on Rails 5.2+
|
1558
|
+
* Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
|
1008
1559
|
|
1009
|
-
*
|
1560
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
1010
1561
|
|
1011
|
-
*
|
1562
|
+
* Add a warning for enum elements with 'not_' prefix.
|
1012
1563
|
|
1013
|
-
|
1564
|
+
class Foo
|
1565
|
+
enum status: [:sent, :not_sent]
|
1566
|
+
end
|
1014
1567
|
|
1015
|
-
*
|
1568
|
+
*Edu Depetris*
|
1016
1569
|
|
1017
|
-
|
1570
|
+
* Make currency symbols optional for money column type in PostgreSQL.
|
1018
1571
|
|
1019
|
-
*
|
1572
|
+
*Joel Schneider*
|
1020
1573
|
|
1021
|
-
*
|
1574
|
+
* Add support for beginless ranges, introduced in Ruby 2.7.
|
1022
1575
|
|
1023
|
-
*
|
1576
|
+
*Josh Goodall*
|
1024
1577
|
|
1025
|
-
*
|
1026
|
-
when the current migration does not exist.
|
1578
|
+
* Add `database_exists?` method to connection adapters to check if a database exists.
|
1027
1579
|
|
1028
|
-
*
|
1580
|
+
*Guilherme Mansur*
|
1029
1581
|
|
1030
|
-
*
|
1582
|
+
* Loading the schema for a model that has no `table_name` raises a `TableNotSpecified` error.
|
1031
1583
|
|
1032
|
-
*
|
1584
|
+
*Guilherme Mansur*, *Eugene Kenny*
|
1033
1585
|
|
1034
|
-
*
|
1586
|
+
* PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
|
1035
1587
|
|
1036
|
-
|
1037
|
-
See https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html.
|
1588
|
+
Fixes #36022.
|
1038
1589
|
|
1039
1590
|
*Ryuta Kamizono*
|
1040
1591
|
|
1041
|
-
*
|
1592
|
+
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
1593
|
+
|
1594
|
+
Fixes #36465.
|
1042
1595
|
|
1043
|
-
*
|
1596
|
+
*Jeff Doering*
|
1597
|
+
|
1598
|
+
* Add support for multiple databases to `rails db:abort_if_pending_migrations`.
|
1599
|
+
|
1600
|
+
*Mark Lee*
|
1601
|
+
|
1602
|
+
* Fix sqlite3 collation parsing when using decimal columns.
|
1603
|
+
|
1604
|
+
*Martin R. Schuster*
|
1605
|
+
|
1606
|
+
* Fix invalid schema when primary key column has a comment.
|
1607
|
+
|
1608
|
+
Fixes #29966.
|
1609
|
+
|
1610
|
+
*Guilherme Goettems Schneider*
|
1611
|
+
|
1612
|
+
* Fix table comment also being applied to the primary key column.
|
1613
|
+
|
1614
|
+
*Guilherme Goettems Schneider*
|
1044
1615
|
|
1045
|
-
*
|
1046
|
-
Previously this method always returned an empty array.
|
1616
|
+
* Allow generated `create_table` migrations to include or skip timestamps.
|
1047
1617
|
|
1048
|
-
*
|
1618
|
+
*Michael Duchemin*
|
1049
1619
|
|
1050
1620
|
|
1051
|
-
Please check [
|
1621
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
|