activerecord 6.0.3.4 → 6.1.0

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

Potentially problematic release.


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

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