activerecord 6.0.4.8 → 6.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

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