activerecord 5.2.6 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +609 -622
- data/MIT-LICENSE +3 -1
- data/README.rdoc +4 -2
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/associations/association.rb +52 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +6 -21
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -10
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +24 -28
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +40 -32
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations.rb +19 -14
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -22
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -53
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +17 -24
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +5 -9
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +5 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
- data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.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 +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
- data/lib/active_record/connection_handling.rb +149 -27
- data/lib/active_record/core.rb +100 -60
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +37 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +145 -472
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -3
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +10 -2
- data/lib/active_record/locking/optimistic.rb +5 -6
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +76 -49
- data/lib/active_record/migration.rb +100 -81
- data/lib/active_record/model_schema.rb +30 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +228 -24
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +32 -20
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +196 -46
- data/lib/active_record/reflection.rb +32 -30
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +53 -47
- data/lib/active_record/relation/delegation.rb +26 -43
- data/lib/active_record/relation/finder_methods.rb +13 -26
- data/lib/active_record/relation/merger.rb +11 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +189 -63
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +14 -10
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +310 -80
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +5 -1
- data/lib/active_record/scoping/default.rb +4 -5
- data/lib/active_record/scoping/named.rb +19 -15
- data/lib/active_record/scoping.rb +8 -8
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/table_metadata.rb +10 -17
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +39 -25
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +57 -66
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record.rb +9 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -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 +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -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 +18 -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 +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -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 +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -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 +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -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 +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +51 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +108 -26
- data/lib/active_record/collection_cache_key.rb +0 -53
data/CHANGELOG.md
CHANGED
@@ -1,1026 +1,1013 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.0.0 (August 16, 2019) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Preserve user supplied joins order as much as possible.
|
4
4
|
|
5
|
+
Fixes #36761, #34328, #24281, #12953.
|
5
6
|
|
6
|
-
|
7
|
+
*Ryuta Kamizono*
|
7
8
|
|
8
|
-
*
|
9
|
+
* Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
|
9
10
|
|
11
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
10
12
|
|
11
|
-
|
13
|
+
* Add a warning for enum elements with 'not_' prefix.
|
12
14
|
|
13
|
-
|
15
|
+
class Foo
|
16
|
+
enum status: [:sent, :not_sent]
|
17
|
+
end
|
14
18
|
|
19
|
+
*Edu Depetris*
|
15
20
|
|
16
|
-
|
21
|
+
* Make currency symbols optional for money column type in PostgreSQL
|
17
22
|
|
18
|
-
*
|
23
|
+
*Joel Schneider*
|
19
24
|
|
20
|
-
Carefully crafted input can cause a DoS via the regular expressions used
|
21
|
-
for validating the money format in the PostgreSQL adapter. This patch
|
22
|
-
fixes the regexp.
|
23
25
|
|
24
|
-
|
26
|
+
## Rails 6.0.0.rc2 (July 22, 2019) ##
|
25
27
|
|
26
|
-
|
28
|
+
* Add database_exists? method to connection adapters to check if a database exists.
|
27
29
|
|
28
|
-
*
|
30
|
+
*Guilherme Mansur*
|
29
31
|
|
32
|
+
* PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
|
30
33
|
|
31
|
-
|
34
|
+
Fixes #36022.
|
32
35
|
|
33
|
-
*
|
36
|
+
*Ryuta Kamizono*
|
34
37
|
|
38
|
+
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
35
39
|
|
36
|
-
|
40
|
+
Fixes #36465.
|
37
41
|
|
38
|
-
*
|
42
|
+
*Jeff Doering*
|
39
43
|
|
40
|
-
|
44
|
+
* Fix sqlite3 collation parsing when using decimal columns.
|
41
45
|
|
42
|
-
*
|
46
|
+
*Martin R. Schuster*
|
43
47
|
|
48
|
+
* Fix invalid schema when primary key column has a comment.
|
44
49
|
|
45
|
-
|
50
|
+
Fixes #29966.
|
46
51
|
|
47
|
-
*
|
52
|
+
*Guilherme Goettems Schneider*
|
48
53
|
|
54
|
+
* Fix table comment also being applied to the primary key column.
|
49
55
|
|
50
|
-
|
56
|
+
*Guilherme Goettems Schneider*
|
51
57
|
|
52
|
-
* Fix
|
58
|
+
* Fix merging left_joins to maintain its own `join_type` context.
|
53
59
|
|
54
|
-
|
55
|
-
associations, the callback for a `has_many` association was run while
|
56
|
-
another instance of the same callback on the same association hadn't
|
57
|
-
finished running. When control returned to the first instance of the
|
58
|
-
callback, the instance variable had changed, and subsequent associated
|
59
|
-
records weren't saved correctly. Specifically, the ID field for the
|
60
|
-
`belongs_to` corresponding to the `has_many` was `nil`.
|
61
|
-
|
62
|
-
Fixes #28080.
|
63
|
-
|
64
|
-
*Larry Reid*
|
65
|
-
|
66
|
-
* PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
|
67
|
-
|
68
|
-
Fixes #36022.
|
60
|
+
Fixes #36103.
|
69
61
|
|
70
62
|
*Ryuta Kamizono*
|
71
63
|
|
72
|
-
* Fix sqlite3 collation parsing when using decimal columns.
|
73
|
-
|
74
|
-
*Martin R. Schuster*
|
75
|
-
|
76
|
-
* Make ActiveRecord `ConnectionPool.connections` method thread-safe.
|
77
64
|
|
78
|
-
|
65
|
+
## Rails 6.0.0.rc1 (April 24, 2019) ##
|
79
66
|
|
80
|
-
|
67
|
+
* Add `touch` option to `has_one` association.
|
81
68
|
|
82
|
-
*
|
83
|
-
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
69
|
+
*Abhay Nikam*
|
84
70
|
|
85
|
-
|
71
|
+
* Deprecate `where.not` working as NOR and will be changed to NAND in Rails 6.1.
|
86
72
|
|
87
|
-
|
73
|
+
```ruby
|
74
|
+
all = [treasures(:diamond), treasures(:sapphire), cars(:honda), treasures(:sapphire)]
|
75
|
+
assert_equal all, PriceEstimate.all.map(&:estimate_of)
|
76
|
+
```
|
88
77
|
|
78
|
+
In Rails 6.0:
|
89
79
|
|
90
|
-
|
80
|
+
```ruby
|
81
|
+
sapphire = treasures(:sapphire)
|
82
|
+
|
83
|
+
nor = all.reject { |e|
|
84
|
+
e.estimate_of_type == sapphire.class.polymorphic_name
|
85
|
+
}.reject { |e|
|
86
|
+
e.estimate_of_id == sapphire.id
|
87
|
+
}
|
88
|
+
assert_equal [cars(:honda)], nor
|
89
|
+
|
90
|
+
without_sapphire = PriceEstimate.where.not(
|
91
|
+
estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
|
92
|
+
)
|
93
|
+
assert_equal nor, without_sapphire.map(&:estimate_of)
|
94
|
+
```
|
91
95
|
|
92
|
-
|
96
|
+
In Rails 6.1:
|
93
97
|
|
94
|
-
|
98
|
+
```ruby
|
99
|
+
sapphire = treasures(:sapphire)
|
95
100
|
|
96
|
-
|
101
|
+
nand = all - [sapphire]
|
102
|
+
assert_equal [treasures(:diamond), cars(:honda)], nand
|
97
103
|
|
98
|
-
|
104
|
+
without_sapphire = PriceEstimate.where.not(
|
105
|
+
estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
|
106
|
+
)
|
107
|
+
assert_equal nand, without_sapphire.map(&:estimate_of)
|
108
|
+
```
|
99
109
|
|
100
110
|
*Ryuta Kamizono*
|
101
111
|
|
102
|
-
*
|
112
|
+
* Fix dirty tracking after rollback.
|
103
113
|
|
104
|
-
Fixes #
|
114
|
+
Fixes #15018, #30167, #33868.
|
105
115
|
|
106
116
|
*Ryuta Kamizono*
|
107
117
|
|
108
|
-
*
|
118
|
+
* Add `ActiveRecord::Relation#cache_version` to support recyclable cache keys via
|
119
|
+
the versioned entries in `ActiveSupport::Cache`. This also means that
|
120
|
+
`ActiveRecord::Relation#cache_key` will now return a stable key that does not
|
121
|
+
include the max timestamp or count any more.
|
109
122
|
|
110
|
-
|
123
|
+
NOTE: This feature is turned off by default, and `cache_key` will still return
|
124
|
+
cache keys with timestamps until you set `ActiveRecord::Base.collection_cache_versioning = true`.
|
125
|
+
That's the setting for all new apps on Rails 6.0+
|
111
126
|
|
112
|
-
*
|
127
|
+
*Lachlan Sylvester*
|
113
128
|
|
114
|
-
* Fix
|
129
|
+
* Fix dirty tracking for `touch` to track saved changes.
|
115
130
|
|
116
|
-
|
131
|
+
Fixes #33429.
|
117
132
|
|
118
|
-
*
|
133
|
+
*Ryuta Kamzono*
|
119
134
|
|
120
|
-
|
135
|
+
* `change_column_comment` and `change_table_comment` are invertible only if
|
136
|
+
`to` and `from` options are specified.
|
121
137
|
|
122
|
-
*
|
138
|
+
*Yoshiyuki Kinjo*
|
123
139
|
|
124
|
-
|
140
|
+
* Don't call commit/rollback callbacks when a record isn't saved.
|
125
141
|
|
142
|
+
Fixes #29747.
|
126
143
|
|
127
|
-
|
144
|
+
*Ryuta Kamizono*
|
128
145
|
|
129
|
-
*
|
146
|
+
* Fix circular `autosave: true` causes invalid records to be saved.
|
130
147
|
|
148
|
+
Prior to the fix, when there was a circular series of `autosave: true`
|
149
|
+
associations, the callback for a `has_many` association was run while
|
150
|
+
another instance of the same callback on the same association hadn't
|
151
|
+
finished running. When control returned to the first instance of the
|
152
|
+
callback, the instance variable had changed, and subsequent associated
|
153
|
+
records weren't saved correctly. Specifically, the ID field for the
|
154
|
+
`belongs_to` corresponding to the `has_many` was `nil`.
|
131
155
|
|
132
|
-
|
156
|
+
Fixes #28080.
|
133
157
|
|
134
|
-
*
|
158
|
+
*Larry Reid*
|
135
159
|
|
136
|
-
|
160
|
+
* Raise `ArgumentError` for invalid `:limit` and `:precision` like as other options.
|
137
161
|
|
138
|
-
|
162
|
+
Before:
|
139
163
|
|
140
|
-
|
164
|
+
```ruby
|
165
|
+
add_column :items, :attr1, :binary, size: 10 # => ArgumentError
|
166
|
+
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
|
167
|
+
add_column :items, :attr3, :integer, limit: 10 # => ActiveRecordError
|
168
|
+
add_column :items, :attr4, :datetime, precision: 10 # => ActiveRecordError
|
169
|
+
```
|
141
170
|
|
142
|
-
|
171
|
+
After:
|
143
172
|
|
144
|
-
|
145
|
-
|
173
|
+
```ruby
|
174
|
+
add_column :items, :attr1, :binary, size: 10 # => ArgumentError
|
175
|
+
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
|
176
|
+
add_column :items, :attr3, :integer, limit: 10 # => ArgumentError
|
177
|
+
add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
|
178
|
+
```
|
146
179
|
|
147
|
-
*
|
180
|
+
*Ryuta Kamizono*
|
148
181
|
|
149
|
-
*
|
182
|
+
* Association loading isn't to be affected by scoping consistently
|
183
|
+
whether preloaded / eager loaded or not, with the exception of `unscoped`.
|
150
184
|
|
151
|
-
|
152
|
-
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
185
|
+
Before:
|
153
186
|
|
154
187
|
```ruby
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
188
|
+
Post.where("1=0").scoping do
|
189
|
+
Comment.find(1).post # => nil
|
190
|
+
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
191
|
+
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
159
192
|
end
|
193
|
+
```
|
160
194
|
|
161
|
-
|
162
|
-
self.table_name = "developers"
|
163
|
-
|
164
|
-
attribute :name, DeveloperName.new
|
195
|
+
After:
|
165
196
|
|
166
|
-
|
197
|
+
```ruby
|
198
|
+
Post.where("1=0").scoping do
|
199
|
+
Comment.find(1).post # => #<Post id: 1, ...>
|
200
|
+
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
|
201
|
+
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
|
167
202
|
end
|
168
|
-
|
169
|
-
developer = AttributedDeveloper.create
|
170
|
-
developer.update_column :name, "name"
|
171
|
-
|
172
|
-
loaded_developer = AttributedDeveloper.where(id: developer.id).select("*").first
|
173
|
-
puts loaded_developer.name # should be "Developer: name" but it's just "name"
|
174
203
|
```
|
175
204
|
|
176
|
-
|
177
|
-
|
178
|
-
* Values of enum are frozen, raising an error when attempting to modify them.
|
179
|
-
|
180
|
-
*Emmanuel Byrd*
|
181
|
-
|
182
|
-
* `update_columns` now correctly raises `ActiveModel::MissingAttributeError`
|
183
|
-
if the attribute does not exist.
|
184
|
-
|
185
|
-
*Sean Griffin*
|
186
|
-
|
187
|
-
* Do not use prepared statement in queries that have a large number of binds.
|
205
|
+
Fixes #34638, #35398.
|
188
206
|
|
189
207
|
*Ryuta Kamizono*
|
190
208
|
|
191
|
-
*
|
209
|
+
* Add `rails db:prepare` to migrate or setup a database.
|
192
210
|
|
193
|
-
|
211
|
+
Runs `db:migrate` if the database exists or `db:setup` if it doesn't.
|
194
212
|
|
195
|
-
*
|
213
|
+
*Roberto Miranda*
|
196
214
|
|
197
|
-
|
215
|
+
* Add `after_save_commit` callback as shortcut for `after_commit :hook, on: [ :create, :update ]`.
|
198
216
|
|
199
|
-
*
|
217
|
+
*DHH*
|
200
218
|
|
201
|
-
*
|
219
|
+
* Assign all attributes before calling `build` to ensure the child record is visible in
|
220
|
+
`before_add` and `after_add` callbacks for `has_many :through` associations.
|
202
221
|
|
203
|
-
|
222
|
+
Fixes #33249.
|
204
223
|
|
205
|
-
*
|
224
|
+
*Ryan H. Kerr*
|
206
225
|
|
207
|
-
|
226
|
+
* Add `ActiveRecord::Relation#extract_associated` for extracting associated records from a relation.
|
208
227
|
|
209
|
-
|
228
|
+
```
|
229
|
+
account.memberships.extract_associated(:user)
|
230
|
+
# => Returns collection of User records
|
231
|
+
```
|
210
232
|
|
211
|
-
*
|
233
|
+
*DHH*
|
212
234
|
|
213
|
-
*
|
235
|
+
* Add `ActiveRecord::Relation#annotate` for adding SQL comments to its queries.
|
214
236
|
|
215
|
-
|
237
|
+
For example:
|
216
238
|
|
217
|
-
|
239
|
+
```
|
240
|
+
Post.where(id: 123).annotate("this is a comment").to_sql
|
241
|
+
# SELECT "posts".* FROM "posts" WHERE "posts"."id" = 123 /* this is a comment */
|
242
|
+
```
|
218
243
|
|
219
|
-
|
244
|
+
This can be useful in instrumentation or other analysis of issued queries.
|
220
245
|
|
221
|
-
*
|
246
|
+
*Matt Yoho*
|
222
247
|
|
223
|
-
|
248
|
+
* Support Optimizer Hints.
|
224
249
|
|
225
|
-
|
250
|
+
In most databases, a way to control the optimizer is by using optimizer hints,
|
251
|
+
which can be specified within individual statements.
|
226
252
|
|
227
|
-
|
253
|
+
Example (for MySQL):
|
228
254
|
|
229
|
-
|
255
|
+
Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
|
256
|
+
# SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
|
230
257
|
|
231
|
-
|
258
|
+
Example (for PostgreSQL with pg_hint_plan):
|
232
259
|
|
260
|
+
Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
|
261
|
+
# SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
233
262
|
|
234
|
-
|
263
|
+
See also:
|
235
264
|
|
236
|
-
*
|
265
|
+
* https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html
|
266
|
+
* https://pghintplan.osdn.jp/pg_hint_plan.html
|
267
|
+
* https://docs.oracle.com/en/database/oracle/oracle-database/12.2/tgsql/influencing-the-optimizer.html
|
268
|
+
* https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-2017
|
269
|
+
* https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.admin.perf.doc/doc/c0070117.html
|
237
270
|
|
271
|
+
*Ryuta Kamizono*
|
238
272
|
|
239
|
-
|
273
|
+
* Fix query attribute method on user-defined attribute to be aware of typecasted value.
|
240
274
|
|
241
|
-
|
275
|
+
For example, the following code no longer return false as casted non-empty string:
|
242
276
|
|
243
|
-
|
277
|
+
```
|
278
|
+
class Post < ActiveRecord::Base
|
279
|
+
attribute :user_defined_text, :text
|
280
|
+
end
|
244
281
|
|
245
|
-
|
282
|
+
Post.new(user_defined_text: "false").user_defined_text? # => true
|
283
|
+
```
|
246
284
|
|
247
|
-
*
|
285
|
+
*Yuji Kamijima*
|
248
286
|
|
249
|
-
|
287
|
+
* Quote empty ranges like other empty enumerables.
|
250
288
|
|
251
|
-
*
|
289
|
+
*Patrick Rebsch*
|
252
290
|
|
253
|
-
|
291
|
+
* Add `insert_all`/`insert_all!`/`upsert_all` methods to `ActiveRecord::Persistence`,
|
292
|
+
allowing bulk inserts akin to the bulk updates provided by `update_all` and
|
293
|
+
bulk deletes by `delete_all`.
|
254
294
|
|
255
|
-
|
295
|
+
Supports skipping or upserting duplicates through the `ON CONFLICT` syntax
|
296
|
+
for PostgreSQL (9.5+) and SQLite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
|
297
|
+
for MySQL.
|
256
298
|
|
257
|
-
*
|
299
|
+
*Bob Lail*
|
258
300
|
|
259
|
-
*
|
301
|
+
* Add `rails db:seed:replant` that truncates tables of each database
|
302
|
+
for current environment and loads the seeds.
|
260
303
|
|
261
|
-
|
304
|
+
*bogdanvlviv*, *DHH*
|
262
305
|
|
263
|
-
|
306
|
+
* Add `ActiveRecord::Base.connection.truncate` for SQLite3 adapter.
|
264
307
|
|
265
|
-
*
|
308
|
+
*bogdanvlviv*
|
266
309
|
|
267
|
-
|
310
|
+
* Deprecate mismatched collation comparison for uniqueness validator.
|
268
311
|
|
269
|
-
|
312
|
+
Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1.
|
313
|
+
To continue case sensitive comparison on the case insensitive column,
|
314
|
+
pass `case_sensitive: true` option explicitly to the uniqueness validator.
|
270
315
|
|
271
|
-
|
316
|
+
*Ryuta Kamizono*
|
272
317
|
|
273
|
-
|
318
|
+
* Add `reselect` method. This is a short-hand for `unscope(:select).select(fields)`.
|
274
319
|
|
275
|
-
|
320
|
+
Fixes #27340.
|
276
321
|
|
277
|
-
|
322
|
+
*Willian Gustavo Veiga*
|
278
323
|
|
279
|
-
|
324
|
+
* Add negative scopes for all enum values.
|
280
325
|
|
281
|
-
|
326
|
+
Example:
|
282
327
|
|
283
|
-
|
328
|
+
class Post < ActiveRecord::Base
|
329
|
+
enum status: %i[ drafted active trashed ]
|
330
|
+
end
|
284
331
|
|
285
|
-
|
332
|
+
Post.not_drafted # => where.not(status: :drafted)
|
333
|
+
Post.not_active # => where.not(status: :active)
|
334
|
+
Post.not_trashed # => where.not(status: :trashed)
|
286
335
|
|
287
|
-
*
|
336
|
+
*DHH*
|
288
337
|
|
289
|
-
|
338
|
+
* Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
|
290
339
|
|
291
|
-
|
292
|
-
wrongly persists through record.
|
340
|
+
Fixes #35214.
|
293
341
|
|
294
|
-
|
342
|
+
*Juani Villarejo*
|
295
343
|
|
296
|
-
*Sam DeCesare*
|
297
344
|
|
298
|
-
|
299
|
-
query cache.
|
345
|
+
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
300
346
|
|
301
|
-
|
347
|
+
* No changes.
|
302
348
|
|
303
349
|
|
304
|
-
## Rails
|
350
|
+
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
305
351
|
|
306
|
-
*
|
352
|
+
* Fix prepared statements caching to be enabled even when query caching is enabled.
|
307
353
|
|
308
|
-
*
|
354
|
+
*Ryuta Kamizono*
|
309
355
|
|
310
|
-
*
|
356
|
+
* Ensure `update_all` series cares about optimistic locking.
|
311
357
|
|
312
|
-
|
313
|
-
have a specified precision then on assignment the value is rounded to
|
314
|
-
that precision. This behavior is now applied to time columns as well.
|
358
|
+
*Ryuta Kamizono*
|
315
359
|
|
316
|
-
|
360
|
+
* Don't allow `where` with non numeric string matches to 0 values.
|
317
361
|
|
318
|
-
*
|
362
|
+
*Ryuta Kamizono*
|
319
363
|
|
320
|
-
*
|
364
|
+
* Introduce `ActiveRecord::Relation#destroy_by` and `ActiveRecord::Relation#delete_by`.
|
321
365
|
|
322
|
-
|
323
|
-
|
324
|
-
component. To ensure that values are consistent we now normalize the
|
325
|
-
date component to 2001-01-01 on reading and writing.
|
366
|
+
`destroy_by` allows relation to find all the records matching the condition and perform
|
367
|
+
`destroy_all` on the matched records.
|
326
368
|
|
327
|
-
|
369
|
+
Example:
|
328
370
|
|
329
|
-
|
371
|
+
Person.destroy_by(name: 'David')
|
372
|
+
Person.destroy_by(name: 'David', rating: 4)
|
330
373
|
|
331
|
-
|
332
|
-
|
333
|
-
date component is removed irrespective of what the date is.
|
374
|
+
david = Person.find_by(name: 'David')
|
375
|
+
david.posts.destroy_by(id: [1, 2, 3])
|
334
376
|
|
335
|
-
|
377
|
+
`delete_by` allows relation to find all the records matching the condition and perform
|
378
|
+
`delete_all` on the matched records.
|
336
379
|
|
337
|
-
|
338
|
-
the parent class was getting deleted when the child was not.
|
380
|
+
Example:
|
339
381
|
|
340
|
-
|
382
|
+
Person.delete_by(name: 'David')
|
383
|
+
Person.delete_by(name: 'David', rating: 4)
|
341
384
|
|
342
|
-
|
385
|
+
david = Person.find_by(name: 'David')
|
386
|
+
david.posts.delete_by(id: [1, 2, 3])
|
343
387
|
|
344
|
-
*
|
388
|
+
*Abhay Nikam*
|
345
389
|
|
346
|
-
|
390
|
+
* Don't allow `where` with invalid value matches to nil values.
|
347
391
|
|
348
|
-
|
392
|
+
Fixes #33624.
|
349
393
|
|
350
394
|
*Ryuta Kamizono*
|
351
395
|
|
352
|
-
*
|
353
|
-
`ActiveRecord::FinderMethods#limited_ids_for` use correct primary key values
|
354
|
-
even if `ORDER BY` columns include other table's primary key.
|
396
|
+
* SQLite3: Implement `add_foreign_key` and `remove_foreign_key`.
|
355
397
|
|
356
|
-
|
357
|
-
|
358
|
-
*Takumi Kagiyama*
|
359
|
-
|
360
|
-
* Make `reflection.klass` raise if `polymorphic?` not to be misused.
|
398
|
+
*Ryuta Kamizono*
|
361
399
|
|
362
|
-
|
400
|
+
* Deprecate using class level querying methods if the receiver scope
|
401
|
+
regarded as leaked. Use `klass.unscoped` to avoid the leaking scope.
|
363
402
|
|
364
403
|
*Ryuta Kamizono*
|
365
404
|
|
366
|
-
*
|
405
|
+
* Allow applications to automatically switch connections.
|
367
406
|
|
368
|
-
|
407
|
+
Adds a middleware and configuration options that can be used in your
|
408
|
+
application to automatically switch between the writing and reading
|
409
|
+
database connections.
|
369
410
|
|
370
|
-
|
371
|
-
|
411
|
+
`GET` and `HEAD` requests will read from the replica unless there was
|
412
|
+
a write in the last 2 seconds, otherwise they will read from the primary.
|
413
|
+
Non-get requests will always write to the primary. The middleware accepts
|
414
|
+
an argument for a Resolver class and an Operations class where you are able
|
415
|
+
to change how the auto-switcher works to be most beneficial for your
|
416
|
+
application.
|
372
417
|
|
373
|
-
|
374
|
-
|
375
|
-
* Fix not expanded problem when passing an Array object as argument to the where method using `composed_of` column.
|
418
|
+
To use the middleware in your application you can use the following
|
419
|
+
configuration options:
|
376
420
|
|
377
421
|
```
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
# Before: WHERE `customers`.`balance` = NULL
|
382
|
-
# After : WHERE `customers`.`balance` = 50
|
422
|
+
config.active_record.database_selector = { delay: 2.seconds }
|
423
|
+
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
|
424
|
+
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
|
383
425
|
```
|
384
426
|
|
385
|
-
|
427
|
+
To change the database selection strategy, pass a custom class to the
|
428
|
+
configuration options:
|
386
429
|
|
387
|
-
|
430
|
+
```
|
431
|
+
config.active_record.database_selector = { delay: 10.seconds }
|
432
|
+
config.active_record.database_resolver = MyResolver
|
433
|
+
config.active_record.database_resolver_context = MyResolver::MyCookies
|
434
|
+
```
|
388
435
|
|
389
|
-
*
|
436
|
+
*Eileen M. Uchitelle*
|
390
437
|
|
391
|
-
|
438
|
+
* MySQL: Support `:size` option to change text and blob size.
|
392
439
|
|
393
440
|
*Ryuta Kamizono*
|
394
441
|
|
395
|
-
*
|
442
|
+
* Make `t.timestamps` with precision by default.
|
396
443
|
|
397
|
-
|
398
|
-
|
399
|
-
*Yuriy Ustushenko*
|
400
|
-
|
401
|
-
* Support for PostgreSQL foreign tables.
|
402
|
-
|
403
|
-
*fatkodima*
|
444
|
+
*Ryuta Kamizono*
|
404
445
|
|
405
|
-
* Fix relation merger issue with `left_outer_joins`.
|
406
446
|
|
407
|
-
|
447
|
+
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
408
448
|
|
409
|
-
*
|
449
|
+
* Remove deprecated `#set_state` from the transaction object.
|
410
450
|
|
411
|
-
*
|
451
|
+
*Rafael Mendonça França*
|
412
452
|
|
413
|
-
*
|
453
|
+
* Remove deprecated `#supports_statement_cache?` from the database adapters.
|
414
454
|
|
415
|
-
|
455
|
+
*Rafael Mendonça França*
|
416
456
|
|
417
|
-
|
457
|
+
* Remove deprecated `#insert_fixtures` from the database adapters.
|
418
458
|
|
419
|
-
*
|
459
|
+
*Rafael Mendonça França*
|
420
460
|
|
421
|
-
|
461
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::SQLite3Adapter#valid_alter_table_type?`.
|
422
462
|
|
423
|
-
|
424
|
-
belongs_to :author
|
425
|
-
has_many :books, through: :author
|
426
|
-
has_many :subscriptions, through: :books
|
427
|
-
end
|
463
|
+
*Rafael Mendonça França*
|
428
464
|
|
429
|
-
|
430
|
-
has_one :post
|
431
|
-
has_many :books
|
432
|
-
has_many :subscriptions, through: :books
|
433
|
-
end
|
465
|
+
* Do not allow passing the column name to `sum` when a block is passed.
|
434
466
|
|
435
|
-
|
436
|
-
belongs_to :author
|
437
|
-
has_many :subscriptions
|
438
|
-
end
|
467
|
+
*Rafael Mendonça França*
|
439
468
|
|
440
|
-
|
441
|
-
belongs_to :book
|
442
|
-
end
|
469
|
+
* Do not allow passing the column name to `count` when a block is passed.
|
443
470
|
|
444
|
-
|
471
|
+
*Rafael Mendonça França*
|
445
472
|
|
446
|
-
|
473
|
+
* Remove delegation of missing methods in a relation to arel.
|
447
474
|
|
448
|
-
|
475
|
+
*Rafael Mendonça França*
|
449
476
|
|
450
|
-
|
451
|
-
just like it would if `post` were persisted.
|
477
|
+
* Remove delegation of missing methods in a relation to private methods of the class.
|
452
478
|
|
453
|
-
|
479
|
+
*Rafael Mendonça França*
|
454
480
|
|
455
|
-
|
481
|
+
* Deprecate `config.activerecord.sqlite3.represent_boolean_as_integer`.
|
456
482
|
|
457
|
-
*
|
458
|
-
The `first(n)` finder now respects the `limit()`, making it consistent
|
459
|
-
with `relation.to_a.first(n)`, and also with the behavior of `last(n)`.
|
483
|
+
*Rafael Mendonça França*
|
460
484
|
|
461
|
-
|
485
|
+
* Change `SQLite3Adapter` to always represent boolean values as integers.
|
462
486
|
|
463
|
-
*
|
487
|
+
*Rafael Mendonça França*
|
464
488
|
|
465
|
-
*
|
466
|
-
SQL queries for association counting.
|
489
|
+
* Remove ability to specify a timestamp name for `#cache_key`.
|
467
490
|
|
468
|
-
*
|
491
|
+
*Rafael Mendonça França*
|
469
492
|
|
470
|
-
*
|
493
|
+
* Remove deprecated `ActiveRecord::Migrator.migrations_path=`.
|
471
494
|
|
472
|
-
*
|
495
|
+
*Rafael Mendonça França*
|
473
496
|
|
474
|
-
*
|
497
|
+
* Remove deprecated `expand_hash_conditions_for_aggregates`.
|
475
498
|
|
476
|
-
*
|
499
|
+
*Rafael Mendonça França*
|
477
500
|
|
478
|
-
*
|
501
|
+
* Set polymorphic type column to NULL on `dependent: :nullify` strategy.
|
479
502
|
|
480
|
-
|
503
|
+
On polymorphic associations both the foreign key and the foreign type columns will be set to NULL.
|
481
504
|
|
482
|
-
*
|
483
|
-
information.
|
505
|
+
*Laerti Papa*
|
484
506
|
|
485
|
-
|
507
|
+
* Allow permitted instance of `ActionController::Parameters` as argument of `ActiveRecord::Relation#exists?`.
|
486
508
|
|
487
|
-
*
|
509
|
+
*Gannon McGibbon*
|
488
510
|
|
489
|
-
|
490
|
-
of database queries in the log to facilitate N+1 query resolution
|
491
|
-
and other debugging.
|
511
|
+
* Add support for endless ranges introduces in Ruby 2.6.
|
492
512
|
|
493
|
-
|
494
|
-
recommended for use in the production environment since it relies
|
495
|
-
on Ruby's `Kernel#caller_locations` which is fairly slow.
|
513
|
+
*Greg Navis*
|
496
514
|
|
497
|
-
|
515
|
+
* Deprecate passing `migrations_paths` to `connection.assume_migrated_upto_version`.
|
498
516
|
|
499
|
-
*
|
517
|
+
*Ryuta Kamizono*
|
500
518
|
|
501
|
-
|
502
|
-
# create_table :posts do |t|
|
503
|
-
# t.integer :comments_count, default: 0
|
504
|
-
# t.integer :lock_version
|
505
|
-
# t.timestamps
|
506
|
-
# end
|
507
|
-
class Post < ApplicationRecord
|
508
|
-
end
|
519
|
+
* MySQL: `ROW_FORMAT=DYNAMIC` create table option by default.
|
509
520
|
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
class Comment < ApplicationRecord
|
514
|
-
belongs_to :post, touch: true, counter_cache: true
|
515
|
-
end
|
516
|
-
```
|
521
|
+
Since MySQL 5.7.9, the `innodb_default_row_format` option defines the default row
|
522
|
+
format for InnoDB tables. The default setting is `DYNAMIC`.
|
523
|
+
The row format is required for indexing on `varchar(255)` with `utf8mb4` columns.
|
517
524
|
|
518
|
-
|
519
|
-
```
|
520
|
-
post = Post.create!
|
521
|
-
# => begin transaction
|
522
|
-
INSERT INTO "posts" ("created_at", "updated_at", "lock_version")
|
523
|
-
VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0)
|
524
|
-
commit transaction
|
525
|
-
|
526
|
-
comment = Comment.create!(post: post)
|
527
|
-
# => begin transaction
|
528
|
-
INSERT INTO "comments" ("post_id") VALUES (1)
|
529
|
-
|
530
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1,
|
531
|
-
"lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1
|
532
|
-
|
533
|
-
UPDATE "posts" SET "updated_at" = '2017-12-11 21:27:11.398330',
|
534
|
-
"lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0
|
535
|
-
rollback transaction
|
536
|
-
# => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post.
|
537
|
-
|
538
|
-
Comment.take.destroy!
|
539
|
-
# => begin transaction
|
540
|
-
DELETE FROM "comments" WHERE "comments"."id" = 1
|
541
|
-
|
542
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1,
|
543
|
-
"lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1
|
544
|
-
|
545
|
-
UPDATE "posts" SET "updated_at" = '2017-12-11 21:42:47.785901',
|
546
|
-
"lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0
|
547
|
-
rollback transaction
|
548
|
-
# => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post.
|
549
|
-
```
|
525
|
+
*Ryuta Kamizono*
|
550
526
|
|
551
|
-
|
552
|
-
```
|
553
|
-
post = Post.create!
|
554
|
-
# => begin transaction
|
555
|
-
INSERT INTO "posts" ("created_at", "updated_at", "lock_version")
|
556
|
-
VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0)
|
557
|
-
commit transaction
|
558
|
-
|
559
|
-
comment = Comment.create!(post: post)
|
560
|
-
# => begin transaction
|
561
|
-
INSERT INTO "comments" ("post_id") VALUES (1)
|
562
|
-
|
563
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1,
|
564
|
-
"lock_version" = COALESCE("lock_version", 0) + 1,
|
565
|
-
"updated_at" = '2017-12-11 21:37:09.802642' WHERE "posts"."id" = 1
|
566
|
-
commit transaction
|
567
|
-
|
568
|
-
comment.destroy!
|
569
|
-
# => begin transaction
|
570
|
-
DELETE FROM "comments" WHERE "comments"."id" = 1
|
571
|
-
|
572
|
-
UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1,
|
573
|
-
"lock_version" = COALESCE("lock_version", 0) + 1,
|
574
|
-
"updated_at" = '2017-12-11 21:39:02.685520' WHERE "posts"."id" = 1
|
575
|
-
commit transaction
|
576
|
-
```
|
527
|
+
* Fix join table column quoting with SQLite.
|
577
528
|
|
578
|
-
|
529
|
+
*Gannon McGibbon*
|
579
530
|
|
580
|
-
|
531
|
+
* Allow disabling scopes generated by `ActiveRecord.enum`.
|
581
532
|
|
582
|
-
*
|
533
|
+
*Alfred Dominic*
|
583
534
|
|
584
|
-
|
535
|
+
* Ensure that `delete_all` on collection proxy returns affected count.
|
585
536
|
|
586
|
-
|
537
|
+
*Ryuta Kamizono*
|
587
538
|
|
588
|
-
|
539
|
+
* Reset scope after delete on collection association to clear stale offsets of removed records.
|
589
540
|
|
590
|
-
*
|
541
|
+
*Gannon McGibbon*
|
591
542
|
|
592
|
-
|
543
|
+
* Add the ability to prevent writes to a database for the duration of a block.
|
593
544
|
|
594
|
-
|
545
|
+
Allows the application to prevent writes to a database. This can be useful when
|
546
|
+
you're building out multiple databases and want to make sure you're not sending
|
547
|
+
writes when you want a read.
|
595
548
|
|
596
|
-
|
597
|
-
|
549
|
+
If `while_preventing_writes` is called and the query is considered a write
|
550
|
+
query the database will raise an exception regardless of whether the database
|
551
|
+
user is able to write.
|
598
552
|
|
599
|
-
|
553
|
+
This is not meant to be a catch-all for write queries but rather a way to enforce
|
554
|
+
read-only queries without opening a second connection. One purpose of this is to
|
555
|
+
catch accidental writes, not all writes.
|
600
556
|
|
601
|
-
*
|
602
|
-
migrating up, e.g. populating a new column.
|
557
|
+
*Eileen M. Uchitelle*
|
603
558
|
|
604
|
-
|
559
|
+
* Allow aliased attributes to be used in `#update_columns` and `#update`.
|
605
560
|
|
606
|
-
*
|
607
|
-
relation query methods.
|
561
|
+
*Gannon McGibbon*
|
608
562
|
|
609
|
-
|
610
|
-
```
|
611
|
-
Article.order("LENGTH(title)")
|
612
|
-
```
|
563
|
+
* Allow spaces in postgres table names.
|
613
564
|
|
614
|
-
|
615
|
-
```
|
616
|
-
Article.order(Arel.sql("LENGTH(title)"))
|
617
|
-
```
|
565
|
+
Fixes issue where "user post" is misinterpreted as "\"user\".\"post\"" when quoting table names with the postgres adapter.
|
618
566
|
|
619
|
-
|
620
|
-
discouraged] form `Article.order(params[:my_order])`, under the
|
621
|
-
mistaken belief that only column names will be accepted.
|
567
|
+
*Gannon McGibbon*
|
622
568
|
|
623
|
-
|
624
|
-
become an UnknownAttributeReference error in Rails 6.0. Applications
|
625
|
-
can opt in to the future behavior by setting `allow_unsafe_raw_sql`
|
626
|
-
to `:disabled`.
|
569
|
+
* Cached `columns_hash` fields should be excluded from `ResultSet#column_types`.
|
627
570
|
|
628
|
-
|
629
|
-
|
630
|
-
```
|
631
|
-
Article.order("title DESC")
|
632
|
-
```
|
571
|
+
PR #34528 addresses the inconsistent behaviour when attribute is defined for an ignored column. The following test
|
572
|
+
was passing for SQLite and MySQL, but failed for PostgreSQL:
|
633
573
|
|
634
|
-
|
574
|
+
```ruby
|
575
|
+
class DeveloperName < ActiveRecord::Type::String
|
576
|
+
def deserialize(value)
|
577
|
+
"Developer: #{value}"
|
578
|
+
end
|
579
|
+
end
|
635
580
|
|
636
|
-
|
637
|
-
|
638
|
-
persist a boolean.
|
581
|
+
class AttributedDeveloper < ActiveRecord::Base
|
582
|
+
self.table_name = "developers"
|
639
583
|
|
640
|
-
|
584
|
+
attribute :name, DeveloperName.new
|
641
585
|
|
642
|
-
|
643
|
-
|
586
|
+
self.ignored_columns += ["name"]
|
587
|
+
end
|
644
588
|
|
645
|
-
|
589
|
+
developer = AttributedDeveloper.create
|
590
|
+
developer.update_column :name, "name"
|
646
591
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
or name of a migration file. Raise error if format of `VERSION` is invalid.
|
651
|
-
Raise error if target migration doesn't exist.
|
592
|
+
loaded_developer = AttributedDeveloper.where(id: developer.id).select("*").first
|
593
|
+
puts loaded_developer.name # should be "Developer: name" but it's just "name"
|
594
|
+
```
|
652
595
|
|
653
|
-
*
|
596
|
+
*Dmitry Tsepelev*
|
654
597
|
|
655
|
-
*
|
656
|
-
`db/schema.rb` when using the sqlite adapter.
|
598
|
+
* Make the implicit order column configurable.
|
657
599
|
|
658
|
-
|
600
|
+
When calling ordered finder methods such as `first` or `last` without an
|
601
|
+
explicit order clause, ActiveRecord sorts records by primary key. This can
|
602
|
+
result in unpredictable and surprising behaviour when the primary key is
|
603
|
+
not an auto-incrementing integer, for example when it's a UUID. This change
|
604
|
+
makes it possible to override the column used for implicit ordering such
|
605
|
+
that `first` and `last` will return more predictable results.
|
659
606
|
|
660
|
-
|
607
|
+
Example:
|
661
608
|
|
662
|
-
|
609
|
+
class Project < ActiveRecord::Base
|
610
|
+
self.implicit_order_column = "created_at"
|
611
|
+
end
|
663
612
|
|
664
|
-
*
|
613
|
+
*Tekin Suleyman*
|
665
614
|
|
666
|
-
*
|
615
|
+
* Bump minimum PostgreSQL version to 9.3.
|
667
616
|
|
668
|
-
*
|
617
|
+
*Yasuo Honda*
|
669
618
|
|
670
|
-
*
|
619
|
+
* Values of enum are frozen, raising an error when attempting to modify them.
|
671
620
|
|
672
|
-
*
|
621
|
+
*Emmanuel Byrd*
|
673
622
|
|
674
|
-
*
|
623
|
+
* Move `ActiveRecord::StatementInvalid` SQL to error property and include binds as separate error property.
|
675
624
|
|
676
|
-
|
625
|
+
`ActiveRecord::ConnectionAdapters::AbstractAdapter#translate_exception_class` now requires `binds` to be passed as the last argument.
|
677
626
|
|
678
|
-
|
627
|
+
`ActiveRecord::ConnectionAdapters::AbstractAdapter#translate_exception` now requires `message`, `sql`, and `binds` to be passed as keyword arguments.
|
679
628
|
|
680
|
-
|
629
|
+
Subclasses of `ActiveRecord::StatementInvalid` must now provide `sql:` and `binds:` arguments to `super`.
|
681
630
|
|
682
|
-
|
631
|
+
Example:
|
683
632
|
|
684
|
-
|
633
|
+
```
|
634
|
+
class MySubclassedError < ActiveRecord::StatementInvalid
|
635
|
+
def initialize(message, sql:, binds:)
|
636
|
+
super(message, sql: sql, binds: binds)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
```
|
685
640
|
|
686
|
-
*
|
641
|
+
*Gannon McGibbon*
|
687
642
|
|
688
|
-
|
643
|
+
* Add an `:if_not_exists` option to `create_table`.
|
689
644
|
|
690
|
-
|
645
|
+
Example:
|
691
646
|
|
692
|
-
|
647
|
+
create_table :posts, if_not_exists: true do |t|
|
648
|
+
t.string :title
|
649
|
+
end
|
693
650
|
|
694
|
-
|
651
|
+
That would execute:
|
695
652
|
|
696
|
-
|
653
|
+
CREATE TABLE IF NOT EXISTS posts (
|
654
|
+
...
|
655
|
+
)
|
697
656
|
|
698
|
-
|
657
|
+
If the table already exists, `if_not_exists: false` (the default) raises an
|
658
|
+
exception whereas `if_not_exists: true` does nothing.
|
699
659
|
|
700
|
-
*
|
660
|
+
*fatkodima*, *Stefan Kanev*
|
701
661
|
|
702
|
-
*
|
662
|
+
* Defining an Enum as a Hash with blank key, or as an Array with a blank value, now raises an `ArgumentError`.
|
703
663
|
|
704
|
-
*
|
664
|
+
*Christophe Maximin*
|
705
665
|
|
706
|
-
*
|
666
|
+
* Adds support for multiple databases to `rails db:schema:cache:dump` and `rails db:schema:cache:clear`.
|
707
667
|
|
708
|
-
*
|
668
|
+
*Gannon McGibbon*
|
709
669
|
|
710
|
-
*
|
670
|
+
* `update_columns` now correctly raises `ActiveModel::MissingAttributeError`
|
671
|
+
if the attribute does not exist.
|
711
672
|
|
712
|
-
*
|
673
|
+
*Sean Griffin*
|
713
674
|
|
714
|
-
*
|
715
|
-
ar_internal_metadata's data for a test database.
|
675
|
+
* Add support for hash and URL configs in database hash of `ActiveRecord::Base.connected_to`.
|
716
676
|
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
key|value|created_at|updated_at
|
722
|
-
environment|development|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679
|
723
|
-
```
|
677
|
+
````
|
678
|
+
User.connected_to(database: { writing: "postgres://foo" }) do
|
679
|
+
User.create!(name: "Gannon")
|
680
|
+
end
|
724
681
|
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
environment|test|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679
|
731
|
-
```
|
682
|
+
config = { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" }
|
683
|
+
User.connected_to(database: { reading: config }) do
|
684
|
+
User.count
|
685
|
+
end
|
686
|
+
````
|
732
687
|
|
733
|
-
|
688
|
+
*Gannon McGibbon*
|
734
689
|
|
735
|
-
|
690
|
+
* Support default expression for MySQL.
|
736
691
|
|
737
|
-
|
692
|
+
MySQL 8.0.13 and higher supports default value to be a function or expression.
|
738
693
|
|
739
|
-
|
694
|
+
https://dev.mysql.com/doc/refman/8.0/en/create-table.html
|
740
695
|
|
741
696
|
*Ryuta Kamizono*
|
742
697
|
|
743
|
-
*
|
744
|
-
|
745
|
-
Fixes #30894.
|
746
|
-
|
747
|
-
*Ryuta Kamizono*
|
698
|
+
* Support expression indexes for MySQL.
|
748
699
|
|
749
|
-
|
700
|
+
MySQL 8.0.13 and higher supports functional key parts that index
|
701
|
+
expression values rather than column or column prefix values.
|
750
702
|
|
751
|
-
|
703
|
+
https://dev.mysql.com/doc/refman/8.0/en/create-index.html
|
752
704
|
|
753
705
|
*Ryuta Kamizono*
|
754
706
|
|
755
|
-
*
|
756
|
-
|
757
|
-
PostgreSQL 9.1+ introduced range types, and Rails added support for using
|
758
|
-
this datatype in Active Record. However, the serialization of
|
759
|
-
`PostgreSQL::OID::Range` was incomplete, because it did not properly
|
760
|
-
cast the bounds that make up the range. This led to subseconds being
|
761
|
-
dropped in SQL commands:
|
707
|
+
* Fix collection cache key with limit and custom select to avoid ambiguous timestamp column error.
|
762
708
|
|
763
|
-
|
709
|
+
Fixes #33056.
|
764
710
|
|
765
|
-
|
766
|
-
# => "[2010-01-01 13:30:00 UTC,2011-02-02 19:30:00 UTC)"
|
711
|
+
*Federico Martinez*
|
767
712
|
|
768
|
-
|
713
|
+
* Add basic API for connection switching to support multiple databases.
|
769
714
|
|
770
|
-
|
771
|
-
# => "[2010-01-01 13:30:00.670277,2011-02-02 19:30:00.745125)"
|
715
|
+
1) Adds a `connects_to` method for models to connect to multiple databases. Example:
|
772
716
|
|
773
|
-
|
717
|
+
```
|
718
|
+
class AnimalsModel < ApplicationRecord
|
719
|
+
self.abstract_class = true
|
774
720
|
|
775
|
-
|
776
|
-
|
721
|
+
connects_to database: { writing: :animals_primary, reading: :animals_replica }
|
722
|
+
end
|
777
723
|
|
778
|
-
|
724
|
+
class Dog < AnimalsModel
|
725
|
+
# connected to both the animals_primary db for writing and the animals_replica for reading
|
726
|
+
end
|
727
|
+
```
|
779
728
|
|
780
|
-
|
729
|
+
2) Adds a `connected_to` block method for switching connection roles or connecting to
|
730
|
+
a database that the model didn't connect to. Connecting to the database in this block is
|
731
|
+
useful when you have another defined connection, for example `slow_replica` that you don't
|
732
|
+
want to connect to by default but need in the console, or a specific code block.
|
781
733
|
|
782
|
-
|
734
|
+
```
|
735
|
+
ActiveRecord::Base.connected_to(role: :reading) do
|
736
|
+
Dog.first # finds dog from replica connected to AnimalsBase
|
737
|
+
Book.first # doesn't have a reading connection, will raise an error
|
738
|
+
end
|
739
|
+
```
|
783
740
|
|
784
|
-
|
741
|
+
```
|
742
|
+
ActiveRecord::Base.connected_to(database: :slow_replica) do
|
743
|
+
SlowReplicaModel.first # if the db config has a slow_replica configuration this will be used to do the lookup, otherwise this will throw an exception
|
744
|
+
end
|
745
|
+
```
|
785
746
|
|
786
|
-
*
|
787
|
-
more descriptive.
|
747
|
+
*Eileen M. Uchitelle*
|
788
748
|
|
789
|
-
|
749
|
+
* Enum raises on invalid definition values
|
790
750
|
|
791
|
-
|
751
|
+
When defining a Hash enum it can be easy to use `[]` instead of `{}`. This
|
752
|
+
commit checks that only valid definition values are provided, those can
|
753
|
+
be a Hash, an array of Symbols or an array of Strings. Otherwise it
|
754
|
+
raises an `ArgumentError`.
|
792
755
|
|
793
|
-
|
794
|
-
when lock wait timeout exceeded.
|
756
|
+
Fixes #33961
|
795
757
|
|
796
|
-
*
|
758
|
+
*Alberto Almagro*
|
797
759
|
|
798
|
-
*
|
760
|
+
* Reloading associations now clears the Query Cache like `Persistence#reload` does.
|
799
761
|
|
800
|
-
|
762
|
+
```
|
763
|
+
class Post < ActiveRecord::Base
|
764
|
+
has_one :category
|
765
|
+
belongs_to :author
|
766
|
+
has_many :comments
|
767
|
+
end
|
801
768
|
|
802
|
-
|
769
|
+
# Each of the following will now clear the query cache.
|
770
|
+
post.reload_category
|
771
|
+
post.reload_author
|
772
|
+
post.comments.reload
|
773
|
+
```
|
803
774
|
|
804
|
-
*
|
775
|
+
*Christophe Maximin*
|
805
776
|
|
806
|
-
*
|
777
|
+
* Added `index` option for `change_table` migration helpers.
|
778
|
+
With this change you can create indexes while adding new
|
779
|
+
columns into the existing tables.
|
807
780
|
|
808
|
-
|
781
|
+
Example:
|
809
782
|
|
810
|
-
|
783
|
+
change_table(:languages) do |t|
|
784
|
+
t.string :country_code, index: true
|
785
|
+
end
|
811
786
|
|
812
|
-
*
|
787
|
+
*Mehmet Emin İNAÇ*
|
813
788
|
|
814
|
-
|
789
|
+
* Fix `transaction` reverting for migrations.
|
815
790
|
|
816
|
-
|
791
|
+
Before: Commands inside a `transaction` in a reverted migration ran uninverted.
|
792
|
+
Now: This change fixes that by reverting commands inside `transaction` block.
|
817
793
|
|
818
|
-
*
|
794
|
+
*fatkodima*, *David Verhasselt*
|
819
795
|
|
820
|
-
*
|
821
|
-
`references` only, as `references` can be implicitly called by `where`.
|
796
|
+
* Raise an error instead of scanning the filesystem root when `fixture_path` is blank.
|
822
797
|
|
823
|
-
|
798
|
+
*Gannon McGibbon*, *Max Albrecht*
|
824
799
|
|
825
|
-
|
800
|
+
* Allow `ActiveRecord::Base.configurations=` to be set with a symbolized hash.
|
826
801
|
|
827
|
-
*
|
828
|
-
need to generate it, it can be created with `rails g application_record`.
|
802
|
+
*Gannon McGibbon*
|
829
803
|
|
830
|
-
|
804
|
+
* Don't update counter cache unless the record is actually saved.
|
831
805
|
|
832
|
-
|
806
|
+
Fixes #31493, #33113, #33117.
|
833
807
|
|
834
808
|
*Ryuta Kamizono*
|
835
809
|
|
836
|
-
*
|
837
|
-
`destroyed_by_association` will now be set to the reflection, matching the
|
838
|
-
behaviour of `has_many` associations.
|
810
|
+
* Deprecate `ActiveRecord::Result#to_hash` in favor of `ActiveRecord::Result#to_a`.
|
839
811
|
|
840
|
-
*
|
812
|
+
*Gannon McGibbon*, *Kevin Cheng*
|
841
813
|
|
842
|
-
*
|
843
|
-
|
844
|
-
When the `where` is called on a relation after a `or`, unscoping the column of that later `where` removed
|
845
|
-
bind values used by the `or` instead. (possibly other cases too)
|
814
|
+
* SQLite3 adapter supports expression indexes.
|
846
815
|
|
847
816
|
```
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
817
|
+
create_table :users do |t|
|
818
|
+
t.string :email
|
819
|
+
end
|
820
|
+
|
821
|
+
add_index :users, 'lower(email)', name: 'index_users_on_email', unique: true
|
853
822
|
```
|
854
823
|
|
855
|
-
*
|
824
|
+
*Gray Kemmey*
|
856
825
|
|
857
|
-
*
|
858
|
-
post-type-cast value for rendering in single-field form inputs.
|
826
|
+
* Allow subclasses to redefine autosave callbacks for associated records.
|
859
827
|
|
860
|
-
|
828
|
+
Fixes #33305.
|
861
829
|
|
862
|
-
*
|
863
|
-
`current_scope`, with the exception of `unscoped`.
|
830
|
+
*Andrey Subbota*
|
864
831
|
|
865
|
-
|
832
|
+
* Bump minimum MySQL version to 5.5.8.
|
866
833
|
|
867
|
-
*
|
834
|
+
*Yasuo Honda*
|
868
835
|
|
869
|
-
*
|
836
|
+
* Use MySQL utf8mb4 character set by default.
|
870
837
|
|
871
|
-
|
872
|
-
|
838
|
+
`utf8mb4` character set with 4-Byte encoding supports supplementary characters including emoji.
|
839
|
+
The previous default 3-Byte encoding character set `utf8` is not enough to support them.
|
873
840
|
|
874
|
-
|
875
|
-
for SQLite databases, so it's implemented behind a configuration flag
|
876
|
-
whose default false value is deprecated.
|
841
|
+
*Yasuo Honda*
|
877
842
|
|
878
|
-
|
843
|
+
* Fix duplicated record creation when using nested attributes with `create_with`.
|
879
844
|
|
880
|
-
*
|
881
|
-
`in_batches`).
|
845
|
+
*Darwin Wu*
|
882
846
|
|
883
|
-
|
884
|
-
|
847
|
+
* Configuration item `config.filter_parameters` could also filter out
|
848
|
+
sensitive values of database columns when calling `#inspect`.
|
849
|
+
We also added `ActiveRecord::Base::filter_attributes`/`=` in order to
|
850
|
+
specify sensitive attributes to specific model.
|
885
851
|
|
886
|
-
|
852
|
+
```
|
853
|
+
Rails.application.config.filter_parameters += [:credit_card_number, /phone/]
|
854
|
+
Account.last.inspect # => #<Account id: 123, name: "DHH", credit_card_number: [FILTERED], telephone_number: [FILTERED] ...>
|
855
|
+
SecureAccount.filter_attributes += [:name]
|
856
|
+
SecureAccount.last.inspect # => #<SecureAccount id: 42, name: [FILTERED], credit_card_number: [FILTERED] ...>
|
857
|
+
```
|
887
858
|
|
888
|
-
*
|
889
|
-
`ActiveRecord::StatementInvalid` exceptions.
|
859
|
+
*Zhang Kang*, *Yoshiyuki Kinjo*
|
890
860
|
|
891
|
-
|
861
|
+
* Deprecate `column_name_length`, `table_name_length`, `columns_per_table`,
|
862
|
+
`indexes_per_table`, `columns_per_multicolumn_index`, `sql_query_length`,
|
863
|
+
and `joins_per_query` methods in `DatabaseLimits`.
|
892
864
|
|
893
|
-
*
|
865
|
+
*Ryuta Kamizono*
|
894
866
|
|
895
|
-
|
867
|
+
* `ActiveRecord::Base.configurations` now returns an object.
|
896
868
|
|
897
|
-
|
869
|
+
`ActiveRecord::Base.configurations` used to return a hash, but this
|
870
|
+
is an inflexible data model. In order to improve multiple-database
|
871
|
+
handling in Rails, we've changed this to return an object. Some methods
|
872
|
+
are provided to make the object behave hash-like in order to ease the
|
873
|
+
transition process. Since most applications don't manipulate the hash
|
874
|
+
we've decided to add backwards-compatible functionality that will throw
|
875
|
+
a deprecation warning if used, however calling `ActiveRecord::Base.configurations`
|
876
|
+
will use the new version internally and externally.
|
898
877
|
|
899
|
-
|
878
|
+
For example, the following `database.yml`:
|
900
879
|
|
901
|
-
|
902
|
-
|
880
|
+
```
|
881
|
+
development:
|
882
|
+
adapter: sqlite3
|
883
|
+
database: db/development.sqlite3
|
884
|
+
```
|
903
885
|
|
904
|
-
|
905
|
-
parent transaction is rolledback. This will correctly mark records from the inner transaction as not persisted.
|
886
|
+
Used to become a hash:
|
906
887
|
|
907
|
-
|
888
|
+
```
|
889
|
+
{ "development" => { "adapter" => "sqlite3", "database" => "db/development.sqlite3" } }
|
890
|
+
```
|
891
|
+
|
892
|
+
Is now converted into the following object:
|
908
893
|
|
909
|
-
|
894
|
+
```
|
895
|
+
#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
896
|
+
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
897
|
+
@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
|
898
|
+
]
|
899
|
+
```
|
910
900
|
|
911
|
-
|
912
|
-
|
913
|
-
|
901
|
+
Iterating over the database configurations has also changed. Instead of
|
902
|
+
calling hash methods on the `configurations` hash directly, a new method `configs_for` has
|
903
|
+
been provided that allows you to select the correct configuration. `env_name` and
|
904
|
+
`spec_name` arguments are optional. For example, these return an array of
|
905
|
+
database config objects for the requested environment and a single database config object
|
906
|
+
will be returned for the requested environment and specification name respectively.
|
914
907
|
|
915
|
-
|
908
|
+
```
|
909
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "development")
|
910
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
|
911
|
+
```
|
916
912
|
|
917
|
-
*
|
913
|
+
*Eileen M. Uchitelle*, *Aaron Patterson*
|
918
914
|
|
919
|
-
|
915
|
+
* Add database configuration to disable advisory locks.
|
920
916
|
|
921
|
-
|
922
|
-
|
917
|
+
```
|
918
|
+
production:
|
919
|
+
adapter: postgresql
|
920
|
+
advisory_locks: false
|
921
|
+
```
|
923
922
|
|
924
|
-
*
|
923
|
+
*Guo Xiang*
|
925
924
|
|
926
|
-
*
|
927
|
-
if the child records were deleted before the parent was saved, they would
|
928
|
-
still be persisted. Now, if child records are deleted before the parent is saved
|
929
|
-
on a `has_many :through` association, the child records will not be persisted.
|
925
|
+
* SQLite3 adapter `alter_table` method restores foreign keys.
|
930
926
|
|
931
|
-
*
|
927
|
+
*Yasuo Honda*
|
932
928
|
|
933
|
-
*
|
934
|
-
the merged relation into LEFT OUTER JOIN.
|
929
|
+
* Allow `:to_table` option to `invert_remove_foreign_key`.
|
935
930
|
|
936
931
|
Example:
|
937
932
|
|
938
|
-
|
939
|
-
Author.joins(:posts).merge(Post.joins(:comments))
|
940
|
-
# Before the change:
|
941
|
-
#=> SELECT ... FROM authors INNER JOIN posts ON ... LEFT OUTER JOIN comments ON...
|
933
|
+
remove_foreign_key :accounts, to_table: :owners
|
942
934
|
|
943
|
-
|
944
|
-
#=> SELECT ... FROM authors INNER JOIN posts ON ... INNER JOIN comments ON...
|
945
|
-
```
|
935
|
+
*Nikolay Epifanov*, *Rich Chen*
|
946
936
|
|
947
|
-
|
937
|
+
* Add environment & load_config dependency to `bin/rake db:seed` to enable
|
938
|
+
seed load in environments without Rails and custom DB configuration
|
948
939
|
|
949
|
-
*
|
950
|
-
`locking_column`, without default value, is null in the database.
|
940
|
+
*Tobias Bielohlawek*
|
951
941
|
|
952
|
-
|
942
|
+
* Fix default value for mysql time types with specified precision.
|
943
|
+
|
944
|
+
*Nikolay Kondratyev*
|
953
945
|
|
954
|
-
* Fix
|
955
|
-
`locking_column` is null in the database.
|
946
|
+
* Fix `touch` option to behave consistently with `Persistence#touch` method.
|
956
947
|
|
957
|
-
*
|
948
|
+
*Ryuta Kamizono*
|
958
949
|
|
959
|
-
*
|
950
|
+
* Migrations raise when duplicate column definition.
|
960
951
|
|
961
|
-
|
952
|
+
Fixes #33024.
|
962
953
|
|
963
|
-
*
|
954
|
+
*Federico Martinez*
|
964
955
|
|
965
|
-
|
956
|
+
* Bump minimum SQLite version to 3.8
|
966
957
|
|
967
|
-
*
|
958
|
+
*Yasuo Honda*
|
968
959
|
|
969
|
-
|
960
|
+
* Fix parent record should not get saved with duplicate children records.
|
970
961
|
|
971
|
-
|
962
|
+
Fixes #32940.
|
972
963
|
|
973
|
-
|
964
|
+
*Santosh Wadghule*
|
974
965
|
|
975
|
-
|
966
|
+
* Fix logic on disabling commit callbacks so they are not called unexpectedly when errors occur.
|
976
967
|
|
977
|
-
*
|
978
|
-
in `ActiveSupport::Cache`. This also means that `ActiveRecord::Base#cache_key` will now return a stable key
|
979
|
-
that does not include a timestamp any more.
|
968
|
+
*Brian Durand*
|
980
969
|
|
981
|
-
|
982
|
-
|
970
|
+
* Ensure `Associations::CollectionAssociation#size` and `Associations::CollectionAssociation#empty?`
|
971
|
+
use loaded association ids if present.
|
983
972
|
|
984
|
-
*
|
973
|
+
*Graham Turner*
|
985
974
|
|
986
|
-
*
|
975
|
+
* Add support to preload associations of polymorphic associations when not all the records have the requested associations.
|
987
976
|
|
988
|
-
*
|
977
|
+
*Dana Sherson*
|
989
978
|
|
990
|
-
* Add
|
979
|
+
* Add `touch_all` method to `ActiveRecord::Relation`.
|
991
980
|
|
992
|
-
|
981
|
+
Example:
|
993
982
|
|
994
|
-
|
983
|
+
Person.where(name: "David").touch_all(time: Time.new(2020, 5, 16, 0, 0, 0))
|
995
984
|
|
996
|
-
*
|
985
|
+
*fatkodima*, *duggiefresh*
|
997
986
|
|
998
|
-
|
987
|
+
* Add `ActiveRecord::Base.base_class?` predicate.
|
999
988
|
|
1000
|
-
*
|
1001
|
-
when the current migration does not exist.
|
989
|
+
*Bogdan Gusiev*
|
1002
990
|
|
1003
|
-
|
991
|
+
* Add custom prefix/suffix options to `ActiveRecord::Store.store_accessor`.
|
1004
992
|
|
1005
|
-
*
|
993
|
+
*Tan Huynh*, *Yukio Mizuta*
|
1006
994
|
|
1007
|
-
|
995
|
+
* Rails 6 requires Ruby 2.5.0 or newer.
|
1008
996
|
|
1009
|
-
*
|
997
|
+
*Jeremy Daer*, *Kasper Timm Hansen*
|
1010
998
|
|
1011
|
-
|
1012
|
-
See https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html.
|
999
|
+
* Deprecate `update_attributes`/`!` in favor of `update`/`!`.
|
1013
1000
|
|
1014
|
-
*
|
1001
|
+
*Eddie Lebow*
|
1015
1002
|
|
1016
|
-
*
|
1003
|
+
* Add `ActiveRecord::Base.create_or_find_by`/`!` to deal with the SELECT/INSERT race condition in
|
1004
|
+
`ActiveRecord::Base.find_or_create_by`/`!` by leaning on unique constraints in the database.
|
1017
1005
|
|
1018
|
-
*
|
1006
|
+
*DHH*
|
1019
1007
|
|
1020
|
-
*
|
1021
|
-
Previously this method always returned an empty array.
|
1008
|
+
* Add `Relation#pick` as short-hand for single-value plucks.
|
1022
1009
|
|
1023
|
-
*
|
1010
|
+
*DHH*
|
1024
1011
|
|
1025
1012
|
|
1026
|
-
Please check [5-
|
1013
|
+
Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activerecord/CHANGELOG.md) for previous changes.
|