activerecord 7.0.8.6 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +631 -1939
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +29 -29
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +16 -13
  7. data/lib/active_record/association_relation.rb +2 -2
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +35 -12
  10. data/lib/active_record/associations/association_scope.rb +16 -9
  11. data/lib/active_record/associations/belongs_to_association.rb +23 -8
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  13. data/lib/active_record/associations/builder/association.rb +3 -3
  14. data/lib/active_record/associations/builder/belongs_to.rb +22 -8
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  16. data/lib/active_record/associations/builder/has_many.rb +3 -4
  17. data/lib/active_record/associations/builder/has_one.rb +3 -4
  18. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  19. data/lib/active_record/associations/collection_association.rb +26 -14
  20. data/lib/active_record/associations/collection_proxy.rb +29 -11
  21. data/lib/active_record/associations/errors.rb +265 -0
  22. data/lib/active_record/associations/foreign_association.rb +10 -3
  23. data/lib/active_record/associations/has_many_association.rb +21 -14
  24. data/lib/active_record/associations/has_many_through_association.rb +17 -7
  25. data/lib/active_record/associations/has_one_association.rb +10 -3
  26. data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
  27. data/lib/active_record/associations/join_dependency.rb +10 -10
  28. data/lib/active_record/associations/nested_error.rb +47 -0
  29. data/lib/active_record/associations/preloader/association.rb +33 -8
  30. data/lib/active_record/associations/preloader/branch.rb +7 -1
  31. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  32. data/lib/active_record/associations/preloader.rb +13 -10
  33. data/lib/active_record/associations/singular_association.rb +7 -1
  34. data/lib/active_record/associations/through_association.rb +22 -11
  35. data/lib/active_record/associations.rb +354 -485
  36. data/lib/active_record/attribute_assignment.rb +0 -4
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  38. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  39. data/lib/active_record/attribute_methods/dirty.rb +53 -35
  40. data/lib/active_record/attribute_methods/primary_key.rb +45 -25
  41. data/lib/active_record/attribute_methods/query.rb +28 -16
  42. data/lib/active_record/attribute_methods/read.rb +8 -7
  43. data/lib/active_record/attribute_methods/serialization.rb +131 -32
  44. data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
  45. data/lib/active_record/attribute_methods/write.rb +6 -6
  46. data/lib/active_record/attribute_methods.rb +148 -33
  47. data/lib/active_record/attributes.rb +64 -50
  48. data/lib/active_record/autosave_association.rb +69 -37
  49. data/lib/active_record/base.rb +9 -5
  50. data/lib/active_record/callbacks.rb +11 -25
  51. data/lib/active_record/coders/column_serializer.rb +61 -0
  52. data/lib/active_record/coders/json.rb +1 -1
  53. data/lib/active_record/coders/yaml_column.rb +70 -42
  54. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +323 -88
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +217 -63
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +307 -129
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +510 -111
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +278 -125
  69. data/lib/active_record/connection_adapters/column.rb +9 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
  72. data/lib/active_record/connection_adapters/mysql/quoting.rb +53 -54
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  76. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
  77. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  78. data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
  79. data/lib/active_record/connection_adapters/pool_config.rb +20 -10
  80. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  87. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  89. data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
  90. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  91. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  92. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
  93. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  94. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +370 -63
  95. data/lib/active_record/connection_adapters/postgresql_adapter.rb +367 -201
  96. data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
  97. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  98. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
  99. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -46
  100. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  101. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
  102. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  103. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +50 -8
  104. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -110
  105. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  106. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  107. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  108. data/lib/active_record/connection_adapters.rb +124 -1
  109. data/lib/active_record/connection_handling.rb +96 -104
  110. data/lib/active_record/core.rb +251 -176
  111. data/lib/active_record/counter_cache.rb +68 -34
  112. data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
  113. data/lib/active_record/database_configurations/database_config.rb +26 -5
  114. data/lib/active_record/database_configurations/hash_config.rb +52 -34
  115. data/lib/active_record/database_configurations/url_config.rb +37 -12
  116. data/lib/active_record/database_configurations.rb +87 -34
  117. data/lib/active_record/delegated_type.rb +39 -10
  118. data/lib/active_record/deprecator.rb +7 -0
  119. data/lib/active_record/destroy_association_async_job.rb +3 -1
  120. data/lib/active_record/dynamic_matchers.rb +2 -2
  121. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  122. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  123. data/lib/active_record/encryption/config.rb +25 -1
  124. data/lib/active_record/encryption/configurable.rb +12 -19
  125. data/lib/active_record/encryption/context.rb +10 -3
  126. data/lib/active_record/encryption/contexts.rb +5 -1
  127. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  128. data/lib/active_record/encryption/encryptable_record.rb +45 -21
  129. data/lib/active_record/encryption/encrypted_attribute_type.rb +47 -12
  130. data/lib/active_record/encryption/encryptor.rb +18 -3
  131. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  132. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  133. data/lib/active_record/encryption/key_generator.rb +12 -1
  134. data/lib/active_record/encryption/key_provider.rb +1 -1
  135. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  136. data/lib/active_record/encryption/message_serializer.rb +6 -0
  137. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  138. data/lib/active_record/encryption/properties.rb +3 -3
  139. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  140. data/lib/active_record/encryption/scheme.rb +22 -21
  141. data/lib/active_record/encryption.rb +3 -0
  142. data/lib/active_record/enum.rb +129 -28
  143. data/lib/active_record/errors.rb +151 -31
  144. data/lib/active_record/explain.rb +21 -12
  145. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  146. data/lib/active_record/fixture_set/render_context.rb +2 -0
  147. data/lib/active_record/fixture_set/table_row.rb +29 -8
  148. data/lib/active_record/fixtures.rb +167 -97
  149. data/lib/active_record/future_result.rb +47 -8
  150. data/lib/active_record/gem_version.rb +4 -4
  151. data/lib/active_record/inheritance.rb +34 -18
  152. data/lib/active_record/insert_all.rb +72 -22
  153. data/lib/active_record/integration.rb +11 -8
  154. data/lib/active_record/internal_metadata.rb +124 -20
  155. data/lib/active_record/locking/optimistic.rb +8 -7
  156. data/lib/active_record/locking/pessimistic.rb +5 -2
  157. data/lib/active_record/log_subscriber.rb +18 -22
  158. data/lib/active_record/marshalling.rb +59 -0
  159. data/lib/active_record/message_pack.rb +124 -0
  160. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  161. data/lib/active_record/middleware/database_selector.rb +6 -8
  162. data/lib/active_record/middleware/shard_selector.rb +3 -1
  163. data/lib/active_record/migration/command_recorder.rb +106 -8
  164. data/lib/active_record/migration/compatibility.rb +147 -5
  165. data/lib/active_record/migration/default_strategy.rb +22 -0
  166. data/lib/active_record/migration/execution_strategy.rb +19 -0
  167. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  168. data/lib/active_record/migration.rb +234 -117
  169. data/lib/active_record/model_schema.rb +90 -102
  170. data/lib/active_record/nested_attributes.rb +48 -11
  171. data/lib/active_record/normalization.rb +163 -0
  172. data/lib/active_record/persistence.rb +168 -339
  173. data/lib/active_record/promise.rb +84 -0
  174. data/lib/active_record/query_cache.rb +18 -25
  175. data/lib/active_record/query_logs.rb +92 -52
  176. data/lib/active_record/query_logs_formatter.rb +41 -0
  177. data/lib/active_record/querying.rb +33 -8
  178. data/lib/active_record/railtie.rb +129 -85
  179. data/lib/active_record/railties/controller_runtime.rb +22 -7
  180. data/lib/active_record/railties/databases.rake +145 -154
  181. data/lib/active_record/railties/job_runtime.rb +23 -0
  182. data/lib/active_record/readonly_attributes.rb +32 -5
  183. data/lib/active_record/reflection.rb +267 -69
  184. data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
  185. data/lib/active_record/relation/batches.rb +198 -63
  186. data/lib/active_record/relation/calculations.rb +250 -93
  187. data/lib/active_record/relation/delegation.rb +30 -19
  188. data/lib/active_record/relation/finder_methods.rb +93 -18
  189. data/lib/active_record/relation/merger.rb +6 -6
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +18 -3
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  193. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  194. data/lib/active_record/relation/predicate_builder.rb +28 -16
  195. data/lib/active_record/relation/query_attribute.rb +2 -1
  196. data/lib/active_record/relation/query_methods.rb +576 -107
  197. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  198. data/lib/active_record/relation/spawn_methods.rb +5 -4
  199. data/lib/active_record/relation/where_clause.rb +7 -19
  200. data/lib/active_record/relation.rb +580 -90
  201. data/lib/active_record/result.rb +49 -48
  202. data/lib/active_record/runtime_registry.rb +63 -1
  203. data/lib/active_record/sanitization.rb +70 -25
  204. data/lib/active_record/schema.rb +8 -7
  205. data/lib/active_record/schema_dumper.rb +63 -14
  206. data/lib/active_record/schema_migration.rb +75 -24
  207. data/lib/active_record/scoping/default.rb +15 -5
  208. data/lib/active_record/scoping/named.rb +3 -2
  209. data/lib/active_record/scoping.rb +2 -1
  210. data/lib/active_record/secure_password.rb +60 -0
  211. data/lib/active_record/secure_token.rb +21 -3
  212. data/lib/active_record/signed_id.rb +27 -6
  213. data/lib/active_record/statement_cache.rb +7 -7
  214. data/lib/active_record/store.rb +8 -8
  215. data/lib/active_record/suppressor.rb +3 -1
  216. data/lib/active_record/table_metadata.rb +1 -1
  217. data/lib/active_record/tasks/database_tasks.rb +190 -118
  218. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  219. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  220. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  221. data/lib/active_record/test_fixtures.rb +170 -155
  222. data/lib/active_record/testing/query_assertions.rb +121 -0
  223. data/lib/active_record/timestamp.rb +31 -17
  224. data/lib/active_record/token_for.rb +123 -0
  225. data/lib/active_record/touch_later.rb +12 -7
  226. data/lib/active_record/transaction.rb +132 -0
  227. data/lib/active_record/transactions.rb +106 -24
  228. data/lib/active_record/translation.rb +0 -2
  229. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  230. data/lib/active_record/type/internal/timezone.rb +7 -2
  231. data/lib/active_record/type/serialized.rb +1 -3
  232. data/lib/active_record/type/time.rb +4 -0
  233. data/lib/active_record/type_caster/connection.rb +4 -4
  234. data/lib/active_record/validations/absence.rb +1 -1
  235. data/lib/active_record/validations/associated.rb +9 -3
  236. data/lib/active_record/validations/numericality.rb +5 -4
  237. data/lib/active_record/validations/presence.rb +5 -28
  238. data/lib/active_record/validations/uniqueness.rb +61 -11
  239. data/lib/active_record/validations.rb +12 -5
  240. data/lib/active_record/version.rb +1 -1
  241. data/lib/active_record.rb +247 -33
  242. data/lib/arel/alias_predication.rb +1 -1
  243. data/lib/arel/collectors/bind.rb +2 -0
  244. data/lib/arel/collectors/composite.rb +7 -0
  245. data/lib/arel/collectors/sql_string.rb +1 -1
  246. data/lib/arel/collectors/substitute_binds.rb +1 -1
  247. data/lib/arel/errors.rb +10 -0
  248. data/lib/arel/factory_methods.rb +4 -0
  249. data/lib/arel/nodes/binary.rb +6 -7
  250. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  251. data/lib/arel/nodes/cte.rb +36 -0
  252. data/lib/arel/nodes/fragments.rb +35 -0
  253. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  254. data/lib/arel/nodes/leading_join.rb +8 -0
  255. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  256. data/lib/arel/nodes/node.rb +115 -5
  257. data/lib/arel/nodes/sql_literal.rb +13 -0
  258. data/lib/arel/nodes/table_alias.rb +4 -0
  259. data/lib/arel/nodes.rb +6 -2
  260. data/lib/arel/predications.rb +3 -1
  261. data/lib/arel/select_manager.rb +1 -1
  262. data/lib/arel/table.rb +9 -5
  263. data/lib/arel/tree_manager.rb +8 -3
  264. data/lib/arel/update_manager.rb +2 -1
  265. data/lib/arel/visitors/dot.rb +1 -0
  266. data/lib/arel/visitors/mysql.rb +17 -5
  267. data/lib/arel/visitors/postgresql.rb +1 -12
  268. data/lib/arel/visitors/sqlite.rb +25 -0
  269. data/lib/arel/visitors/to_sql.rb +112 -34
  270. data/lib/arel/visitors/visitor.rb +2 -2
  271. data/lib/arel.rb +21 -3
  272. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  273. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  274. data/lib/rails/generators/active_record/migration.rb +3 -1
  275. data/lib/rails/generators/active_record/model/USAGE +113 -0
  276. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  277. metadata +56 -14
  278. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  279. data/lib/active_record/null_relation.rb +0 -63
data/CHANGELOG.md CHANGED
@@ -1,2406 +1,1098 @@
1
- ## Rails 7.0.8.6 (October 23, 2024) ##
1
+ ## Rails 7.2.2.1 (December 10, 2024) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 7.0.8.5 (October 15, 2024) ##
7
-
8
- * No changes.
9
-
10
-
11
- ## Rails 7.0.8.4 (June 04, 2024) ##
12
-
13
- * No changes.
6
+ ## Rails 7.2.2 (October 30, 2024) ##
14
7
 
8
+ * Fix support for `query_cache: false` in `database.yml`.
15
9
 
16
- ## Rails 7.0.8.3 (May 17, 2024) ##
10
+ `query_cache: false` would no longer entirely disable the Active Record query cache.
17
11
 
18
- * No changes.
12
+ *zzak*
19
13
 
14
+ * Set `.attributes_for_inspect` to `:all` by default.
20
15
 
21
- ## Rails 7.0.8.2 (May 16, 2024) ##
16
+ For new applications it is set to `[:id]` in config/environment/production.rb.
22
17
 
23
- * No changes.
18
+ In the console all the attributes are always shown.
24
19
 
20
+ *Andrew Novoselac*
25
21
 
26
- ## Rails 7.0.8.1 (February 21, 2024) ##
22
+ * `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
27
23
 
28
- * No changes.
24
+ *Kazuma Watanabe*
29
25
 
26
+ * Fix marshalling of unsaved associated records in 7.1 format.
30
27
 
31
- ## Rails 7.0.8 (September 09, 2023) ##
28
+ The 7.1 format would only marshal associated records if the association was loaded.
29
+ But associations that would only contain unsaved records would be skipped.
32
30
 
33
- * Fix `change_column` not setting `precision: 6` on `datetime` columns when
34
- using 7.0+ Migrations and SQLite.
31
+ *Jean Boussier*
35
32
 
36
- *Hartley McGuire*
33
+ * Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
37
34
 
38
- * Fix unscope is not working in specific case
35
+ *David Stosik*
39
36
 
40
- Before:
41
- ```ruby
42
- Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
37
+ * Allow to save records with polymorphic join tables that have `inverse_of`
38
+ specified.
43
39
 
44
- ```
40
+ *Markus Doits*
45
41
 
46
- After:
47
- ```ruby
48
- Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
49
- ```
42
+ * Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
50
43
 
51
- Fixes #48094.
44
+ *Joshua Young*
52
45
 
53
- *Kazuya Hatanaka*
46
+ * Fix `dependent: :destroy` for bi-directional has one through association.
54
47
 
55
- * Fix associations to a STI model including a `class_name` parameter
48
+ Fixes #50948.
56
49
 
57
50
  ```ruby
58
- class Product < ApplicationRecord
59
- has_many :requests, as: :requestable, class_name: "ProductRequest", dependent: :destroy
51
+ class Left < ActiveRecord::Base
52
+ has_one :middle, dependent: :destroy
53
+ has_one :right, through: :middle
60
54
  end
61
55
 
62
- # STI tables
63
- class Request < ApplicationRecord
64
- belongs_to :requestable, polymorphic: true
65
-
66
- validate :request_type, presence: true
56
+ class Middle < ActiveRecord::Base
57
+ belongs_to :left, dependent: :destroy
58
+ belongs_to :right, dependent: :destroy
67
59
  end
68
60
 
69
- class ProductRequest < Request
70
- belongs_to :user
61
+ class Right < ActiveRecord::Base
62
+ has_one :middle, dependent: :destroy
63
+ has_one :left, through: :middle
71
64
  end
72
65
  ```
66
+ In the above example `left.destroy` wouldn't destroy its associated `Right`
67
+ record.
73
68
 
74
- Accessing such association would lead to:
75
-
76
- ```
77
- table_metadata.rb:22:in `has_column?': undefined method `key?' for nil:NilClass (NoMethodError)
78
- ```
69
+ *Andy Stewart*
79
70
 
80
- *Romain Filinto*
71
+ * Properly handle lazily pinned connection pools.
81
72
 
82
- * Fix `change_table` setting datetime precision for 6.1 Migrations
73
+ Fixes #53147.
83
74
 
84
- *Hartley McGuire*
75
+ When using transactional fixtures with system tests to similar tools
76
+ such as capybara, it could happen that a connection end up pinned by the
77
+ server thread rather than the test thread, causing
78
+ `"Cannot expire connection, it is owned by a different thread"` errors.
85
79
 
86
- * Fix change_column setting datetime precision for 6.1 Migrations
80
+ *Jean Boussier*
87
81
 
88
- *Hartley McGuire*
82
+ * Fix `ActiveRecord::Base.with` to accept more than two sub queries.
89
83
 
90
- ## Rails 7.0.7.2 (August 22, 2023) ##
84
+ Fixes #53110.
91
85
 
92
- * No changes.
86
+ ```ruby
87
+ User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
88
+ undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
89
+ ```
93
90
 
91
+ The above now works as expected.
94
92
 
95
- ## Rails 7.0.7.1 (August 22, 2023) ##
93
+ *fatkodima*
96
94
 
97
- * No changes.
95
+ * Properly release pinned connections with non joinable connections.
98
96
 
97
+ Fixes #52973
99
98
 
100
- ## Rails 7.0.7 (August 09, 2023) ##
99
+ When running system tests with transactional fixtures on, it could happen that
100
+ the connection leased by the Puma thread wouldn't be properly released back to the pool,
101
+ causing "Cannot expire connection, it is owned by a different thread" errors in later tests.
101
102
 
102
- * Restores functionality to the missing method when using enums and fixes.
103
+ *Jean Boussier*
103
104
 
104
- *paulreece*
105
+ * Make Float distinguish between `float4` and `float8` in PostgreSQL.
105
106
 
106
- * Fix `StatementCache::Substitute` with serialized type.
107
+ Fixes #52742
107
108
 
108
- *ywenc*
109
+ *Ryota Kitazawa*, *Takayuki Nagatomi*
109
110
 
110
- * Fix `:db_runtime` on notification payload when application have multiple databases.
111
+ * Fix an issue where `.left_outer_joins` used with multiple associations that have
112
+ the same child association but different parents does not join all parents.
111
113
 
112
- *Eileen M. Uchitelle*
114
+ Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
113
115
 
114
- * Correctly dump check constraints for MySQL 8.0.16+.
116
+ Now it will correctly join both parents.
115
117
 
116
- *Steve Hill*
118
+ Fixes #41498.
117
119
 
118
- * Fix `ActiveRecord::QueryMethods#in_order_of` to include `nil`s, to match the
119
- behavior of `Enumerable#in_order_of`.
120
+ *Garrett Blehm*
120
121
 
121
- For example, `Post.in_order_of(:title, [nil, "foo"])` will now include posts
122
- with `nil` titles, the same as `Post.all.to_a.in_order_of(:title, [nil, "foo"])`.
122
+ * Ensure `ActiveRecord::Encryption.config` is always ready before access.
123
123
 
124
- *fatkodima*
124
+ Previously, `ActiveRecord::Encryption` configuration was deferred until `ActiveRecord::Base`
125
+ was loaded. Therefore, accessing `ActiveRecord::Encryption.config` properties before
126
+ `ActiveRecord::Base` was loaded would give incorrect results.
125
127
 
126
- * Revert "Fix autosave associations with validations added on `:base` of the associated objects."
128
+ `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
129
+ soon as needed.
127
130
 
128
- This change intended to remove the :base attribute from the message,
129
- but broke many assumptions which key these errors were stored.
131
+ When `ActiveRecord::Base` is loaded, even lazily, it in turn triggers the loading of
132
+ `ActiveRecord::Encryption`, thus preserving the original behavior of having its config ready
133
+ before any use of `ActiveRecord::Base`.
130
134
 
131
- *zzak*
135
+ *Maxime Réty*
132
136
 
133
- * Fix `#previously_new_record?` to return true for destroyed records.
137
+ * Add `TimeZoneConverter#==` method, so objects will be properly compared by
138
+ their type, scale, limit & precision.
134
139
 
135
- Before, if a record was created and then destroyed, `#previously_new_record?` would return true.
136
- Now, any UPDATE or DELETE to a record is considered a change, and will result in `#previously_new_record?`
137
- returning false.
140
+ Address #52699.
138
141
 
139
- *Adrianna Chang*
142
+ *Ruy Rocha*
140
143
 
141
- * Revert breaking changes to `has_one` relationship deleting the old record before the new one is validated.
142
144
 
143
- *zzak*
145
+ ## Rails 7.2.1.2 (October 23, 2024) ##
144
146
 
145
- * Fix support for Active Record instances being uses in queries.
147
+ * No changes.
146
148
 
147
- As of `7.0.5`, query arguments were deep duped to avoid mutations impacting
148
- the query cache, but this had the adverse effect to clearing the primary key when
149
- the query argument contained an `ActiveRecord::Base` instance.
150
149
 
151
- This broke the `noticed` gem.
150
+ ## Rails 7.2.1.1 (October 15, 2024) ##
152
151
 
153
- *Jean Boussier*
152
+ * No changes.
154
153
 
155
154
 
156
- ## Rails 7.0.6 (June 29, 2023) ##
155
+ ## Rails 7.2.1 (August 22, 2024) ##
157
156
 
158
- * Fix autosave associations with validations added on `:base` of the associated objects.
157
+ * Fix detection for `enum` columns with parallelized tests and PostgreSQL.
159
158
 
160
- *fatkodima*
159
+ *Rafael Mendonça França*
161
160
 
162
- * Fix result with anonymous PostgreSQL columns of different type from json.
161
+ * Allow to eager load nested nil associations.
163
162
 
164
- *Oleksandr Avoiants*
163
+ *fatkodima*
165
164
 
166
- * Preserve timestamp when setting an `ActiveSupport::TimeWithZone` value to `timestamptz` attribute.
165
+ * Fix swallowing ignore order warning when batching using `BatchEnumerator`.
167
166
 
168
167
  *fatkodima*
169
168
 
170
- * Fix assignment into an `has_one` relationship deleting the old record before the new one is validated.
169
+ * Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
171
170
 
172
171
  *Jean Boussier*
173
172
 
174
- * Fix where on association with has_one/has_many polymorphic relations.
175
-
176
- Before:
177
- ```ruby
178
- Treasure.where(price_estimates: PriceEstimate.all)
179
- #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
180
- ```
173
+ * Restore inferred association class with the same modularized name.
181
174
 
182
- Later:
183
- ```ruby
184
- Treasure.where(price_estimates: PriceEstimate.all)
185
- #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
186
- ```
175
+ *Justin Ko*
187
176
 
188
- *Lázaro Nixon*
177
+ * Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
189
178
 
190
- * Fix decrementing counter caches on optimistically locked record deletion
179
+ *Jean Boussier*
191
180
 
192
- *fatkodima*
181
+ * Check invalid `enum` options for the new syntax.
193
182
 
194
- * Ensure binary-destined values have binary encoding during type cast.
183
+ The options using `_` prefix in the old syntax are invalid in the new syntax.
195
184
 
196
- *Matthew Draper*
185
+ *Rafael Mendonça França*
197
186
 
198
- * Preserve existing column default functions when altering table in SQLite.
187
+ * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
188
+ actual cast type.
199
189
 
200
- *fatkodima*
190
+ *Vasiliy Ermolovich*
201
191
 
202
- * Remove table alias added when using `where.missing` or `where.associated`.
192
+ * Fix `create_table` with `:auto_increment` option for MySQL adapter.
203
193
 
204
194
  *fatkodima*
205
195
 
206
- * Fix `Enumerable#in_order_of` to only flatten first level to preserve nesting.
207
196
 
208
- *Miha Rekar*
197
+ ## Rails 7.2.0 (August 09, 2024) ##
209
198
 
199
+ * Handle commas in Sqlite3 default function definitions.
210
200
 
211
- ## Rails 7.0.5.1 (June 26, 2023) ##
201
+ *Stephen Margheim*
212
202
 
213
- * No changes.
203
+ * Fixes `validates_associated` raising an exception when configured with a
204
+ singular association and having `index_nested_attribute_errors` enabled.
214
205
 
215
- ## Rails 7.0.5 (May 24, 2023) ##
206
+ *Martin Spickermann*
216
207
 
217
- * Type cast `#attribute_changed?` `:from` and `:to` options.
208
+ * The constant `ActiveRecord::ImmutableRelation` has been deprecated because
209
+ we want to reserve that name for a stronger sense of "immutable relation".
210
+ Please use `ActiveRecord::UnmodifiableRelation` instead.
218
211
 
219
- *Andrew Novoselac*
212
+ *Xavier Noria*
220
213
 
221
- * Fix `index_exists?` when column is an array.
214
+ * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
215
+ `DatabaseConfig`.
222
216
 
223
- *Eileen M. Uchitelle*
217
+ *Hartley McGuire*
224
218
 
225
- * Handle `Date` objects for PostgreSQL `timestamptz` columns.
219
+ * Fixed a memory performance issue in Active Record attribute methods definition.
226
220
 
227
- *Alex Ghiculescu*
221
+ *Jean Boussier*
228
222
 
229
- * Fix collation for changing column to non-string.
223
+ * Define the new Active Support notification event `start_transaction.active_record`.
230
224
 
231
- *Hartley McGuire*
225
+ This event is fired when database transactions or savepoints start, and
226
+ complements `transaction.active_record`, which is emitted when they finish.
232
227
 
233
- * Map through subtype in `PostgreSQL::OID::Array`.
228
+ The payload has the transaction (`:transaction`) and the connection (`:connection`).
234
229
 
235
- *Jonathan Hefner*
230
+ *Xavier Noria*
236
231
 
237
- * Store correct environment in `internal_metadata` when run rails `db:prepare`.
232
+ * Fix an issue where the IDs reader method did not return expected results
233
+ for preloaded associations in models using composite primary keys.
238
234
 
239
- *fatkodima*
235
+ *Jay Ang*
240
236
 
241
- * Make sure `ActiveRecord::Relation#sum` works with objects that implement `#coerce` without deprecation.
237
+ * The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
242
238
 
243
- *Alex Ghiculescu*
239
+ *Xavier Noria*
244
240
 
245
- * Fix retrieving foreign keys referencing tables named like keywords in PostgreSQL and MySQL.
241
+ * The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
246
242
 
247
- *fatkodima*
243
+ *Xavier Noria*
248
244
 
249
- * Support UUIDs in Disable Joins.
245
+ * Define `ActiveRecord::Transaction#uuid`, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.
250
246
 
251
- *Samuel Cochran*
247
+ *Xavier Noria*
252
248
 
253
- * Fix Active Record's explain for queries starting with comments.
249
+ * Fix inference of association model on nested models with the same demodularized name.
254
250
 
255
- *fatkodima*
251
+ E.g. with the following setup:
252
+
253
+ ```ruby
254
+ class Nested::Post < ApplicationRecord
255
+ has_one :post, through: :other
256
+ end
257
+ ```
256
258
 
257
- * Fix incorrectly preloading through association records when middle association has been loaded.
259
+ Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
258
260
 
259
261
  *Joshua Young*
260
262
 
261
- * Fix where.missing and where.associated for parent/child associations.
263
+ * PostgreSQL `Cidr#change?` detects the address prefix change.
262
264
 
263
- *fatkodima*
265
+ *Taketo Takashima*
264
266
 
265
- * Fix Enumerable#in_order_of to preserve duplicates.
267
+ * Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
266
268
 
267
- *fatkodima*
269
+ Previously, it always returned `nil`.
268
270
 
269
- * Fix autoincrement on primary key for mysql.
271
+ *fatkodima*
270
272
 
271
- *Eileen M. Uchitelle*
273
+ * Support `touch_all` in batches.
272
274
 
273
- * Restore ability to redefine column in `create_table` for Rails 5.2 migrations.
275
+ ```ruby
276
+ Post.in_batches.touch_all
277
+ ```
274
278
 
275
279
  *fatkodima*
276
280
 
277
- * Fix schema cache dumping of virtual columns.
281
+ * Add support for `:if_not_exists` and `:force` options to `create_schema`.
278
282
 
279
283
  *fatkodima*
280
284
 
281
- * Fix Active Record grouped calculations on joined tables on column present in both tables.
285
+ * Fix `index_errors` having incorrect index in association validation errors.
282
286
 
283
- *fatkodima*
287
+ *lulalala*
284
288
 
285
- * Fix mutation detection for serialized attributes backed by binary columns.
289
+ * Add `index_errors: :nested_attributes_order` mode.
286
290
 
287
- *Jean Boussier*
291
+ This indexes the association validation errors based on the order received by nested attributes setter, and respects the `reject_if` configuration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.
288
292
 
289
- * Fix a bug where using groups and counts with long table names would return incorrect results.
293
+ *lulalala*
290
294
 
291
- *Shota Toguchi*, *Yusaku Ono*
295
+ * Add `Rails.application.config.active_record.postgresql_adapter_decode_dates` to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.
292
296
 
293
- * Fix erroneous nil default precision on virtual datetime columns.
297
+ *Joé Dupuis*
294
298
 
295
- Prior to this change, virtual datetime columns did not have the same
296
- default precision as regular datetime columns, resulting in the following
297
- being erroneously equivalent:
299
+ * Association option `query_constraints` is deprecated in favor of `foreign_key`.
298
300
 
299
- t.virtual :name, type: datetime, as: "expression"
300
- t.virtual :name, type: datetime, precision: nil, as: "expression"
301
+ *Nikita Vasilevsky*
301
302
 
302
- This change fixes the default precision lookup, so virtual and regular
303
- datetime column default precisions match.
303
+ * Add `ENV["SKIP_TEST_DATABASE_TRUNCATE"]` flag to speed up multi-process test runs on large DBs when all tests run within default transaction.
304
304
 
305
- *Sam Bostock*
305
+ This cuts ~10s from the test run of HEY when run by 24 processes against the 178 tables, since ~4,000 table truncates can then be skipped.
306
306
 
307
- * Fix a case where the query cache can return wrong values. See #46044
307
+ *DHH*
308
308
 
309
- *Aaron Patterson*
309
+ * Added support for recursive common table expressions.
310
310
 
311
+ ```ruby
312
+ Post.with_recursive(
313
+ post_and_replies: [
314
+ Post.where(id: 42),
315
+ Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
316
+ ]
317
+ )
318
+ ```
311
319
 
312
- ## Rails 7.0.4.3 (March 13, 2023) ##
320
+ Generates the following SQL:
313
321
 
314
- * No changes.
322
+ ```sql
323
+ WITH RECURSIVE "post_and_replies" AS (
324
+ (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
325
+ UNION ALL
326
+ (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
327
+ )
328
+ SELECT "posts".* FROM "posts"
329
+ ```
315
330
 
331
+ *ClearlyClaire*
316
332
 
317
- ## Rails 7.0.4.2 (January 24, 2023) ##
333
+ * `validate_constraint` can be called in a `change_table` block.
318
334
 
319
- * No changes.
335
+ ex:
336
+ ```ruby
337
+ change_table :products do |t|
338
+ t.check_constraint "price > discounted_price", name: "price_check", validate: false
339
+ t.validate_check_constraint "price_check"
340
+ end
341
+ ```
320
342
 
343
+ *Cody Cutrer*
321
344
 
322
- ## Rails 7.0.4.1 (January 17, 2023) ##
345
+ * `PostgreSQLAdapter` now decodes columns of type date to `Date` instead of string.
323
346
 
324
- * Make sanitize_as_sql_comment more strict
347
+ Ex:
348
+ ```ruby
349
+ ActiveRecord::Base.connection
350
+ .select_value("select '2024-01-01'::date").class #=> Date
351
+ ```
325
352
 
326
- Though this method was likely never meant to take user input, it was
327
- attempting sanitization. That sanitization could be bypassed with
328
- carefully crafted input.
353
+ *Joé Dupuis*
329
354
 
330
- This commit makes the sanitization more robust by replacing any
331
- occurrences of "/*" or "*/" with "/ *" or "* /". It also performs a
332
- first pass to remove one surrounding comment to avoid compatibility
333
- issues for users relying on the existing removal.
355
+ * Strict loading using `:n_plus_one_only` does not eagerly load child associations.
334
356
 
335
- This also clarifies in the documentation of annotate that it should not
336
- be provided user input.
357
+ With this change, child associations are no longer eagerly loaded, to
358
+ match intended behavior and to prevent non-deterministic order issues caused
359
+ by calling methods like `first` or `last`. As `first` and `last` don't cause
360
+ an N+1 by themselves, calling child associations will no longer raise.
361
+ Fixes #49473.
337
362
 
338
- [CVE-2023-22794]
363
+ Before:
339
364
 
340
- * Added integer width check to PostgreSQL::Quoting
365
+ ```ruby
366
+ person = Person.find(1)
367
+ person.strict_loading!(mode: :n_plus_one_only)
368
+ person.posts.first
369
+ # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
370
+ person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
371
+ ```
341
372
 
342
- Given a value outside the range for a 64bit signed integer type
343
- PostgreSQL will treat the column type as numeric. Comparing
344
- integer values against numeric values can result in a slow
345
- sequential scan.
373
+ After:
346
374
 
347
- This behavior is configurable via
348
- ActiveRecord::Base.raise_int_wider_than_64bit which defaults to true.
375
+ ```ruby
376
+ person = Person.find(1)
377
+ person.strict_loading!(mode: :n_plus_one_only)
378
+ person.posts.first # this is 1+1, not N+1
379
+ # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
380
+ person.posts.first.firm # no longer raises
381
+ ```
349
382
 
350
- [CVE-2022-44566]
383
+ *Reid Lynch*
351
384
 
385
+ * Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
352
386
 
353
- ## Rails 7.0.4 (September 09, 2022) ##
387
+ *Mike Dalessio*
354
388
 
355
- * Symbol is allowed by default for YAML columns
389
+ * Allow `ActiveRecord::Base#pluck` to accept hash values.
356
390
 
357
- *Étienne Barrié*
391
+ ```ruby
392
+ # Before
393
+ Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
358
394
 
359
- * Fix `ActiveRecord::Store` to serialize as a regular Hash
395
+ # After
396
+ Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
397
+ ```
360
398
 
361
- Previously it would serialize as an `ActiveSupport::HashWithIndifferentAccess`
362
- which is wasteful and cause problem with YAML safe_load.
399
+ *fatkodima*
363
400
 
364
- *Jean Boussier*
401
+ * Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
365
402
 
366
- * Add `timestamptz` as a time zone aware type for PostgreSQL
403
+ *Kevin McPhillips*
367
404
 
368
- This is required for correctly parsing `timestamp with time zone` values in your database.
405
+ * `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
369
406
 
370
- If you don't want this, you can opt out by adding this initializer:
407
+ This allows to register callbacks on it.
371
408
 
372
409
  ```ruby
373
- ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
410
+ Article.transaction do |transaction|
411
+ article.update(published: true)
412
+ transaction.after_commit do
413
+ PublishNotificationMailer.with(article: article).deliver_later
414
+ end
415
+ end
374
416
  ```
375
417
 
376
- *Alex Ghiculescu*
418
+ *Jean Boussier*
419
+
420
+ * Add `ActiveRecord::Base.current_transaction`.
377
421
 
378
- * Fix supporting timezone awareness for `tsrange` and `tstzrange` array columns.
422
+ Returns the current transaction, to allow registering callbacks on it.
379
423
 
380
424
  ```ruby
381
- # In database migrations
382
- add_column :shops, :open_hours, :tsrange, array: true
383
- # In app config
384
- ActiveRecord::Base.time_zone_aware_types += [:tsrange]
385
- # In the code times are properly converted to app time zone
386
- Shop.create!(open_hours: [Time.current..8.hour.from_now])
425
+ Article.current_transaction.after_commit do
426
+ PublishNotificationMailer.with(article: article).deliver_later
427
+ end
387
428
  ```
388
429
 
389
- *Wojciech Wnętrzak*
390
-
391
- * Resolve issue where a relation cache_version could be left stale.
430
+ *Jean Boussier*
392
431
 
393
- Previously, when `reset` was called on a relation object it did not reset the cache_versions
394
- ivar. This led to a confusing situation where despite having the correct data the relation
395
- still reported a stale cache_version.
432
+ * Add `ActiveRecord.after_all_transactions_commit` callback.
396
433
 
397
- Usage:
434
+ Useful for code that may run either inside or outside a transaction and needs
435
+ to perform work after the state changes have been properly persisted.
398
436
 
399
437
  ```ruby
400
- developers = Developer.all
401
- developers.cache_version
438
+ def publish_article(article)
439
+ article.update(published: true)
440
+ ActiveRecord.after_all_transactions_commit do
441
+ PublishNotificationMailer.with(article: article).deliver_later
442
+ end
443
+ end
444
+ ```
402
445
 
403
- Developer.update_all(updated_at: Time.now.utc + 1.second)
446
+ In the above example, the block is either executed immediately if called outside
447
+ of a transaction, or called after the open transaction is committed.
404
448
 
405
- developers.cache_version # Stale cache_version
406
- developers.reset
407
- developers.cache_version # Returns the current correct cache_version
408
- ```
449
+ If the transaction is rolled back, the block isn't called.
409
450
 
410
- Fixes #45341.
451
+ *Jean Boussier*
411
452
 
412
- *Austen Madden*
453
+ * Add the ability to ignore counter cache columns until they are backfilled.
413
454
 
414
- * Fix `load_async` when called on an association proxy.
455
+ Starting to use counter caches on existing large tables can be troublesome, because the column
456
+ values must be backfilled separately of the column addition (to not lock the table for too long)
457
+ and before the use of `:counter_cache` (otherwise methods like `size`/`any?`/etc, which use
458
+ counter caches internally, can produce incorrect results). People usually use database triggers
459
+ or callbacks on child associations while backfilling before introducing a counter cache
460
+ configuration to the association.
415
461
 
416
- Calling `load_async` directly an association would schedule
417
- a query but never use it.
462
+ Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
418
463
 
419
464
  ```ruby
420
- comments = post.comments.load_async # schedule a query
421
- comments.to_a # perform an entirely new sync query
465
+ class Comment < ApplicationRecord
466
+ belongs_to :post, counter_cache: { active: false }
467
+ end
422
468
  ```
423
469
 
424
- Now it does use the async query, however note that it doesn't
425
- cause the association to be loaded.
470
+ While the counter cache is not "active", the methods like `size`/`any?`/etc will not use it,
471
+ but get the results directly from the database. After the counter cache column is backfilled, simply
472
+ remove the `{ active: false }` part from the counter cache definition, and it will now be used by the
473
+ mentioned methods.
426
474
 
427
- *Jean Boussier*
428
-
429
- * Fix eager loading for models without primary keys.
475
+ *fatkodima*
430
476
 
431
- *Anmol Chopra*, *Matt Lawrence*, and *Jonathan Hefner*
477
+ * Retry known idempotent SELECT queries on connection-related exceptions.
432
478
 
433
- * `rails db:schema:{dump,load}` now checks `ENV["SCHEMA_FORMAT"]` before config
479
+ SELECT queries we construct by walking the Arel tree and / or with known model attributes
480
+ are idempotent and can safely be retried in the case of a connection error. Previously,
481
+ adapters such as `TrilogyAdapter` would raise `ActiveRecord::ConnectionFailed: Trilogy::EOFError`
482
+ when encountering a connection error mid-request.
434
483
 
435
- Since `rails db:structure:{dump,load}` was deprecated there wasn't a simple
436
- way to dump a schema to both SQL and Ruby formats. You can now do this with
437
- an environment variable. For example:
484
+ *Adrianna Chang*
438
485
 
439
- ```
440
- SCHEMA_FORMAT=sql rake db:schema:dump
441
- ```
486
+ * Allow association's `foreign_key` to be composite.
442
487
 
443
- *Alex Ghiculescu*
488
+ `query_constraints` option was the only way to configure a composite foreign key by passing an `Array`.
489
+ Now it's possible to pass an Array value as `foreign_key` to achieve the same behavior of an association.
444
490
 
445
- * Fix Hstore deserialize regression.
491
+ *Nikita Vasilevsky*
446
492
 
447
- *edsharp*
493
+ * Allow association's `primary_key` to be composite.
448
494
 
495
+ Association's `primary_key` can be composite when derived from associated model `primary_key` or `query_constraints`.
496
+ Now it's possible to explicitly set it as composite on the association.
449
497
 
450
- ## Rails 7.0.3.1 (July 12, 2022) ##
498
+ *Nikita Vasilevsky*
451
499
 
452
- * Change ActiveRecord::Coders::YAMLColumn default to safe_load
500
+ * Add `config.active_record.permanent_connection_checkout` setting.
453
501
 
454
- This adds two new configuration options The configuration options are as
455
- follows:
502
+ Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
456
503
 
457
- * `config.active_record.use_yaml_unsafe_load`
504
+ `ActiveRecord::Base.connection` checkouts a database connection from the pool and keeps it leased until the end of
505
+ the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
506
+ is available connections.
458
507
 
459
- When set to true, this configuration option tells Rails to use the old
460
- "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
461
- the possible escalation vulnerability in place. Setting this option to true
462
- is *not* recommended, but can aid in upgrading.
508
+ This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
509
+ migrate it to use `ActiveRecord::Base.with_connection` instead.
463
510
 
464
- * `config.active_record.yaml_column_permitted_classes`
511
+ The default behavior remains unchanged, and there is currently no plans to change the default.
465
512
 
466
- The "safe YAML" loading method does not allow all classes to be deserialized
467
- by default. This option allows you to specify classes deemed "safe" in your
468
- application. For example, if your application uses Symbol and Time in
469
- serialized data, you can add Symbol and Time to the allowed list as follows:
513
+ *Jean Boussier*
470
514
 
471
- ```
472
- config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
473
- ```
515
+ * Add dirties option to uncached.
474
516
 
475
- [CVE-2022-32224]
517
+ This adds a `dirties` option to `ActiveRecord::Base.uncached` and
518
+ `ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
476
519
 
520
+ When set to `true` (the default), writes will clear all query caches belonging to the current thread.
521
+ When set to `false`, writes to the affected connection pool will not clear any query cache.
477
522
 
478
- ## Rails 7.0.3 (May 09, 2022) ##
523
+ This is needed by Solid Cache so that cache writes do not clear query caches.
479
524
 
480
- * Some internal housekeeping on reloads could break custom `respond_to?`
481
- methods in class objects that referenced reloadable constants. See
482
- [#44125](https://github.com/rails/rails/issues/44125) for details.
525
+ *Donal McBreen*
483
526
 
484
- *Xavier Noria*
527
+ * Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
485
528
 
486
- * Fixed MariaDB default function support.
529
+ The method has been renamed as `lease_connection` to better reflect that the returned
530
+ connection will be held for the duration of the request or job.
487
531
 
488
- Defaults would be written wrong in "db/schema.rb" and not work correctly
489
- if using `db:schema:load`. Further more the function name would be
490
- added as string content when saving new records.
532
+ This deprecation is a soft deprecation, no warnings will be issued and there is no
533
+ current plan to remove the method.
491
534
 
492
- *kaspernj*
535
+ *Jean Boussier*
493
536
 
494
- * Fix `remove_foreign_key` with `:if_exists` option when foreign key actually exists.
537
+ * Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
495
538
 
496
- *fatkodima*
539
+ The method has been renamed as `lease_connection` to better reflect that the returned
540
+ connection will be held for the duration of the request or job.
497
541
 
498
- * Remove `--no-comments` flag in structure dumps for PostgreSQL
542
+ *Jean Boussier*
499
543
 
500
- This broke some apps that used custom schema comments. If you don't want
501
- comments in your structure dump, you can use:
544
+ * Expose a generic fixture accessor for fixture names that may conflict with Minitest.
502
545
 
503
546
  ```ruby
504
- ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
547
+ assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
548
+ assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
505
549
  ```
506
550
 
507
- *Alex Ghiculescu*
551
+ *Jean Boussier*
508
552
 
509
- * Use the model name as a prefix when filtering encrypted attributes from logs.
553
+ * Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
554
+ incorrect error message.
510
555
 
511
- For example, when encrypting `Person#name` it will add `person.name` as a filter
512
- parameter, instead of just `name`. This prevents unintended filtering of parameters
513
- with a matching name in other models.
556
+ This has been fixed to raise with a more appropriate error message.
514
557
 
515
- *Jorge Manrubia*
558
+ *Joshua Young*
516
559
 
517
- * Fix quoting of `ActiveSupport::Duration` and `Rational` numbers in the MySQL adapter.
560
+ * Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
518
561
 
519
- *Kevin McPhillips*
562
+ This behavior is also inconsistent with autosaving `belongs_to` and can have unintended side effects like raising
563
+ an `ActiveRecord::ReadonlyAttributeError` when the foreign key attribute is marked as read-only.
520
564
 
521
- * Fix `change_column_comment` to preserve column's AUTO_INCREMENT in the MySQL adapter
565
+ *Joshua Young*
522
566
 
523
- *fatkodima*
567
+ * Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
524
568
 
525
- ## Rails 7.0.2.4 (April 26, 2022) ##
569
+ *Rafael Mendonça França*
526
570
 
527
- * No changes.
571
+ * Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
528
572
 
573
+ *Rafael Mendonça França*
529
574
 
530
- ## Rails 7.0.2.3 (March 08, 2022) ##
575
+ * Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
531
576
 
532
- * No changes.
577
+ *Rafael Mendonça França*
533
578
 
579
+ * Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
534
580
 
535
- ## Rails 7.0.2.2 (February 11, 2022) ##
581
+ *Rafael Mendonça França*
536
582
 
537
- * No changes.
583
+ * Remove deprecated support to quote `ActiveSupport::Duration`.
538
584
 
585
+ *Rafael Mendonça França*
539
586
 
540
- ## Rails 7.0.2.1 (February 11, 2022) ##
587
+ * Remove deprecated `#quote_bound_value`.
541
588
 
542
- * No changes.
589
+ *Rafael Mendonça França*
543
590
 
591
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
544
592
 
545
- ## Rails 7.0.2 (February 08, 2022) ##
593
+ *Rafael Mendonça França*
546
594
 
547
- * Fix `PG.connect` keyword arguments deprecation warning on ruby 2.7.
595
+ * Remove deprecated support to apply `#connection_pool_list`, `#active_connections?`, `#clear_active_connections!`,
596
+ `#clear_reloadable_connections!`, `#clear_all_connections!` and `#flush_idle_connections!` to the connections pools
597
+ for the current role when the `role` argument isn't provided.
548
598
 
549
- *Nikita Vasilevsky*
599
+ *Rafael Mendonça França*
550
600
 
551
- * Fix the ability to exclude encryption params from being autofiltered.
601
+ * Remove deprecated `#all_connection_pools`.
552
602
 
553
- *Mark Gangl*
603
+ *Rafael Mendonça França*
554
604
 
555
- * Dump the precision for datetime columns following the new defaults.
605
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
556
606
 
557
607
  *Rafael Mendonça França*
558
608
 
559
- * Make sure encrypted attributes are not being filtered twice.
609
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
560
610
 
561
- *Nikita Vasilevsky*
611
+ *Rafael Mendonça França*
562
612
 
563
- * Dump the database schema containing the current Rails version.
613
+ * Remove deprecated `#all_foreign_keys_valid?` from database adapters.
564
614
 
565
- Since https://github.com/rails/rails/pull/42297, Rails now generate datetime columns
566
- with a default precision of 6. This means that users upgrading to Rails 7.0 from 6.1,
567
- when loading the database schema, would get the new precision value, which would not match
568
- the production schema.
615
+ *Rafael Mendonça França*
569
616
 
570
- To avoid this the schema dumper will generate the new format which will include the Rails
571
- version and will look like this:
617
+ * Remove deprecated support to passing coder and class as second argument to `serialize`.
572
618
 
573
- ```
574
- ActiveRecord::Schema[7.0].define
575
- ```
619
+ *Rafael Mendonça França*
576
620
 
577
- When upgrading from Rails 6.1 to Rails 7.0, you can run the `rails app:update` task that will
578
- set the current schema version to 6.1.
621
+ * Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
579
622
 
580
623
  *Rafael Mendonça França*
581
624
 
582
- * Fix parsing expression for PostgreSQL generated column.
625
+ * Remove deprecated `TestFixtures.fixture_path`.
583
626
 
584
- *fatkodima*
627
+ *Rafael Mendonça França*
585
628
 
586
- * Fix `Mysql2::Error: Commands out of sync; you can't run this command now`
587
- when bulk-inserting fixtures that exceed `max_allowed_packet` configuration.
629
+ * Remove deprecated behavior to support referring to a singular association by its plural name.
588
630
 
589
- *Nikita Vasilevsky*
631
+ *Rafael Mendonça França*
590
632
 
591
- * Fix error when saving an association with a relation named `record`.
633
+ * Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
592
634
 
593
- *Dorian Marié*
635
+ *Rafael Mendonça França*
636
+
637
+ * Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
638
+ `ActiveRecord::MigrationContext`.
594
639
 
595
- * Fix `MySQL::SchemaDumper` behavior about datetime precision value.
640
+ *Rafael Mendonça França*
596
641
 
597
- *y0t4*
642
+ * Remove deprecated `ActiveRecord::Migration.check_pending!` method.
598
643
 
599
- * Improve associated with no reflection error.
644
+ *Rafael Mendonça França*
600
645
 
601
- *Nikolai*
646
+ * Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
602
647
 
603
- * Fix PG.connect keyword arguments deprecation warning on ruby 2.7.
648
+ *Rafael Mendonça França*
604
649
 
605
- Fixes #44307.
650
+ * Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
606
651
 
607
- *Nikita Vasilevsky*
652
+ *Rafael Mendonça França*
608
653
 
609
- * Fix passing options to `check_constraint` from `change_table`.
654
+ * Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
610
655
 
611
- *Frederick Cheung*
656
+ *Rafael Mendonça França*
612
657
 
658
+ * Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
613
659
 
614
- ## Rails 7.0.1 (January 06, 2022) ##
660
+ *Rafael Mendonça França*
615
661
 
662
+ * Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
616
663
 
617
- * Change `QueryMethods#in_order_of` to drop records not listed in values.
664
+ *Rafael Mendonça França*
618
665
 
619
- `in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version.
666
+ * Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
620
667
 
621
- *Kevin Newton*
668
+ *Rafael Mendonça França*
622
669
 
623
- * Allow named expression indexes to be revertible.
670
+ * Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
624
671
 
625
- Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.
672
+ *Rafael Mendonça França*
626
673
 
627
- ```ruby
628
- add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
629
- ```
674
+ * Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
630
675
 
631
- Fixes #43331.
676
+ *Rafael Mendonça França*
632
677
 
633
- *Oliver Günther*
678
+ * Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
634
679
 
635
- * Better error messages when association name is invalid in the argument of `ActiveRecord::QueryMethods::WhereChain#missing`.
680
+ *Rafael Mendonça França*
636
681
 
637
- *ykpythemind*
682
+ * Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
638
683
 
639
- * Fix ordered migrations for single db in multi db environment.
684
+ *Rafael Mendonça França*
640
685
 
641
- *Himanshu*
686
+ * Remove deprecated support to call `alias_attribute` with non-existent attribute names.
642
687
 
643
- * Extract `on update CURRENT_TIMESTAMP` for mysql2 adapter.
688
+ *Rafael Mendonça França*
644
689
 
645
- *Kazuhiro Masuda*
690
+ * Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
646
691
 
647
- * Fix incorrect argument in PostgreSQL structure dump tasks.
692
+ *Rafael Mendonça França*
648
693
 
649
- Updating the `--no-comment` argument added in Rails 7 to the correct `--no-comments` argument.
694
+ * Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
650
695
 
651
- *Alex Dent*
696
+ Serialize data to the MessagePack format, for efficient storage in binary columns.
652
697
 
653
- * Fix schema dumping column default SQL values for sqlite3.
698
+ The binary encoding requires around 30% less space than the base64 encoding
699
+ used by the default serializer.
654
700
 
655
- *fatkodima*
701
+ *Donal McBreen*
656
702
 
657
- * Correctly parse complex check constraint expressions for PostgreSQL.
703
+ * Add support for encrypting binary columns.
658
704
 
659
- *fatkodima*
705
+ Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
660
706
 
661
- * Fix `timestamptz` attributes on PostgreSQL handle blank inputs.
707
+ Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
708
+ incidentally worked for MySQL and SQLite, but not PostgreSQL.
662
709
 
663
- *Alex Ghiculescu*
710
+ *Donal McBreen*
664
711
 
665
- * Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.
712
+ * Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
666
713
 
667
- Reference/belongs_to in migrations with version 6.0 were creating columns as
668
- bigint instead of integer for the SQLite Adapter.
714
+ *Rafael Mendonça França*
669
715
 
670
- *Marcelo Lauxen*
716
+ * Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
671
717
 
672
- * Fix joining through a polymorphic association.
718
+ The leased connection is yielded, and for the duration of the block, any call to `ActiveRecord::Base.connection`
719
+ will yield that same connection.
673
720
 
674
- *Alexandre Ruban*
721
+ This is useful to perform a few database operations without causing a connection to be leased for the
722
+ entire duration of the request or job.
675
723
 
676
- * Fix `QueryMethods#in_order_of` to handle empty order list.
724
+ *Jean Boussier*
677
725
 
678
- ```ruby
679
- Post.in_order_of(:id, []).to_a
680
- ```
726
+ * Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
727
+ notification includes `:row_count` field.
681
728
 
682
- Also more explicitly set the column as secondary order, so that any other
683
- value is still ordered.
729
+ *Jason Nochlin*
684
730
 
685
- *Jean Boussier*
731
+ * The fix ensures that the association is joined using the appropriate join type
732
+ (either inner join or left outer join) based on the existing joins in the scope.
686
733
 
687
- * Fix `rails dbconsole` for 3-tier config.
734
+ This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
688
735
 
689
- *Eileen M. Uchitelle*
736
+ Example:
690
737
 
691
- * Fix quoting of column aliases generated by calculation methods.
692
738
 
693
- Since the alias is derived from the table name, we can't assume the result
694
- is a valid identifier.
695
739
 
696
740
  ```ruby
697
- class Test < ActiveRecord::Base
698
- self.table_name = '1abc'
699
- end
700
- Test.group(:id).count
701
- # syntax error at or near "1" (ActiveRecord::StatementInvalid)
702
- # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
741
+ # `associated` will use `LEFT JOIN` instead of using `JOIN`
742
+ Post.left_joins(:author).where.associated(:author)
703
743
  ```
704
744
 
705
- *Jean Boussier*
745
+ *Saleh Alhaddad*
706
746
 
747
+ * Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
748
+ of Active Record models, when an application is eager loaded. As a result, encrypted attributes
749
+ could be misconfigured in some cases.
707
750
 
708
- ## Rails 7.0.0 (December 15, 2021) ##
751
+ *Maxime Réty*
709
752
 
710
- * Better handle SQL queries with invalid encoding.
753
+ * Deprecate defining an `enum` with keyword arguments.
711
754
 
712
755
  ```ruby
713
- Post.create(name: "broken \xC8 UTF-8")
714
- ```
756
+ class Function > ApplicationRecord
757
+ # BAD
758
+ enum color: [:red, :blue],
759
+ type: [:instance, :class]
715
760
 
716
- Would cause all adapters to fail in a non controlled way in the code
717
- responsible to detect write queries.
761
+ # GOOD
762
+ enum :color, [:red, :blue]
763
+ enum :type, [:instance, :class]
764
+ end
765
+ ```
718
766
 
719
- The query is now properly passed to the database connection, which might or might
720
- not be able to handle it, but will either succeed or failed in a more correct way.
767
+ *Hartley McGuire*
721
768
 
722
- *Jean Boussier*
769
+ * Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
723
770
 
724
- * Move database and shard selection config options to a generator.
771
+ When set, validates that the timestamp prefix for a migration is no more than a day ahead of
772
+ the timestamp associated with the current time. This is designed to prevent migrations prefixes
773
+ from being hand-edited to future timestamps, which impacts migration generation and other
774
+ migration commands.
725
775
 
726
- Rather than generating the config options in `production.rb` when applications are created, applications can now run a generator to create an initializer and uncomment / update options as needed. All multi-db configuration can be implemented in this initializer.
776
+ *Adrianna Chang*
727
777
 
728
- *Eileen M. Uchitelle*
778
+ * Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
729
779
 
780
+ As well as `disconnect!` and `verify!`.
730
781
 
731
- ## Rails 7.0.0.rc3 (December 14, 2021) ##
782
+ This generally isn't a big problem as connections must not be shared between
783
+ threads, but is required when running transactional tests or system tests
784
+ and could lead to a SEGV.
732
785
 
733
- * No changes.
786
+ *Jean Boussier*
734
787
 
788
+ * Support `:source_location` tag option for query log tags.
735
789
 
736
- ## Rails 7.0.0.rc2 (December 14, 2021) ##
790
+ ```ruby
791
+ config.active_record.query_log_tags << :source_location
792
+ ```
737
793
 
738
- * No changes.
794
+ Calculating the caller location is a costly operation and should be used primarily in development
795
+ (note, there is also a `config.active_record.verbose_query_logs` that serves the same purpose)
796
+ or occasionally on production for debugging purposes.
739
797
 
798
+ *fatkodima*
740
799
 
741
- ## Rails 7.0.0.rc1 (December 06, 2021) ##
800
+ * Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
742
801
 
743
- * Remove deprecated `ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name`.
802
+ Allow compression to be disabled by setting `compress: false`
744
803
 
745
- *Rafael Mendonça França*
804
+ ```ruby
805
+ class User
806
+ encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
807
+ end
808
+ ```
746
809
 
747
- * Remove deprecated `ActiveRecord::Connection#in_clause_length`.
810
+ *Donal McBreen*
748
811
 
749
- *Rafael Mendonça França*
812
+ * Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
750
813
 
751
- * Remove deprecated `ActiveRecord::Connection#allowed_index_name_length`.
814
+ A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
752
815
 
753
816
  *Rafael Mendonça França*
754
817
 
755
- * Remove deprecated `ActiveRecord::Base#remove_connection`.
756
-
757
- *Rafael Mendonça França*
818
+ * Add `row_count` field to `sql.active_record` notification.
758
819
 
759
- * Load STI Models in fixtures
820
+ This field returns the amount of rows returned by the query that emitted the notification.
760
821
 
761
- Data from Fixtures now loads based on the specific class for models with
762
- Single Table Inheritance. This affects enums defined in subclasses, previously
763
- the value of these fields was not parsed and remained `nil`
822
+ This metric is useful in cases where one wants to detect queries with big result sets.
764
823
 
765
- *Andres Howard*
824
+ *Marvin Bitterlich*
766
825
 
767
- * `#authenticate` returns false when the password is blank instead of raising an error.
826
+ * Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
768
827
 
769
- *Muhammad Muhammad Ibrahim*
828
+ Previously, this would only raise on collection associations and produce a generic error on singular associations.
770
829
 
771
- * Fix `ActiveRecord::QueryMethods#in_order_of` behavior for integer enums.
830
+ Now, it will raise on both collection and singular associations.
772
831
 
773
- `ActiveRecord::QueryMethods#in_order_of` didn't work as expected for enums stored as integers in the database when passing an array of strings or symbols as the order argument. This unexpected behavior occurred because the string or symbol values were not casted to match the integers in the database.
832
+ *Joshua Young*
774
833
 
775
- The following example now works as expected:
834
+ * Fix single quote escapes on default generated MySQL columns.
776
835
 
777
- ```ruby
778
- class Book < ApplicationRecord
779
- enum status: [:proposed, :written, :published]
780
- end
836
+ MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
781
837
 
782
- Book.in_order_of(:status, %w[written published proposed])
783
- ```
838
+ Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
784
839
 
785
- *Alexandre Ruban*
840
+ This would result in issues when importing the schema on a fresh instance of a MySQL database.
786
841
 
787
- * Ignore persisted in-memory records when merging target lists.
842
+ Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
788
843
 
789
- *Kevin Sjöberg*
844
+ *Yash Kapadia*
790
845
 
791
- * Add a new option `:update_only` to `upsert_all` to configure the list of columns to update in case of conflict.
846
+ * Fix Migrations with versions older than 7.1 validating options given to
847
+ `add_reference` and `t.references`.
792
848
 
793
- Before, you could only customize the update SQL sentence via `:on_duplicate`. There is now a new option `:update_only` that lets you provide a list of columns to update in case of conflict:
849
+ *Hartley McGuire*
794
850
 
795
- ```ruby
796
- Commodity.upsert_all(
797
- [
798
- { id: 2, name: "Copper", price: 4.84 },
799
- { id: 4, name: "Gold", price: 1380.87 },
800
- { id: 6, name: "Aluminium", price: 0.35 }
801
- ],
802
- update_only: [:price] # Only prices will be updated
803
- )
804
- ```
851
+ * Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
805
852
 
806
- *Jorge Manrubia*
853
+ *JP Rosevear*
807
854
 
808
- * Remove deprecated `ActiveRecord::Result#map!` and `ActiveRecord::Result#collect!`.
855
+ * Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
809
856
 
810
- *Rafael Mendonça França*
857
+ This wouldn't always work previously because boolean values would be interpreted as strings.
811
858
 
812
- * Remove deprecated `ActiveRecord::Base.configurations.to_h`.
859
+ e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
860
+ cache.
813
861
 
814
- *Rafael Mendonça França*
862
+ *Mike Coutermarsh*, *Jean Boussier*
815
863
 
816
- * Remove deprecated `ActiveRecord::Base.configurations.default_hash`.
864
+ * Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
817
865
 
818
- *Rafael Mendonça França*
866
+ It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
867
+ but with support for `after_commit` and `after_rollback` callback options.
819
868
 
820
- * Remove deprecated `ActiveRecord::Base.arel_attribute`.
869
+ *Joshua Young*
821
870
 
822
- *Rafael Mendonça França*
871
+ * Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
823
872
 
824
- * Remove deprecated `ActiveRecord::Base.connection_config`.
873
+ Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
825
874
 
826
- *Rafael Mendonça França*
875
+ Now, the encryptor lets the configured `message_serializer` decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize `ActiveRecord::Encryption::Message` objects using a type other than `String`.
827
876
 
828
- * Filter attributes in SQL logs
877
+ The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
829
878
 
830
- Previously, SQL queries in logs containing `ActiveRecord::Base.filter_attributes` were not filtered.
879
+ *Maxime Réty*
831
880
 
832
- Now, the filter attributes will be masked `[FILTERED]` in the logs when `prepared_statement` is enabled.
881
+ * Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
833
882
 
834
- ```
835
- # Before:
836
- Foo Load (0.2ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "hello"], ["LIMIT", 1]]
883
+ *Maxime Réty*
837
884
 
838
- # After:
839
- Foo Load (0.5ms) SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ? [["passw", "[FILTERED]"], ["LIMIT", 1]]
840
- ```
885
+ * The object returned by `explain` now responds to `pluck`, `first`,
886
+ `last`, `average`, `count`, `maximum`, `minimum`, and `sum`. Those
887
+ new methods run `EXPLAIN` on the corresponding queries:
841
888
 
842
- *Aishwarya Subramanian*
889
+ ```ruby
890
+ User.all.explain.count
891
+ # EXPLAIN SELECT COUNT(*) FROM `users`
892
+ # ...
843
893
 
844
- * Remove deprecated `Tasks::DatabaseTasks.spec`.
894
+ User.all.explain.maximum(:id)
895
+ # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
896
+ # ...
897
+ ```
845
898
 
846
- *Rafael Mendonça França*
899
+ *Petrik de Heus*
847
900
 
848
- * Remove deprecated `Tasks::DatabaseTasks.current_config`.
901
+ * Fixes an issue where `validates_associated` `:on` option wasn't respected
902
+ when validating associated records.
849
903
 
850
- *Rafael Mendonça França*
904
+ *Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
851
905
 
852
- * Deprecate `Tasks::DatabaseTasks.schema_file_type`.
906
+ * Allow overriding SQLite defaults from `database.yml`.
853
907
 
854
- *Rafael Mendonça França*
908
+ Any PRAGMA configuration set under the `pragmas` key in the configuration
909
+ file takes precedence over Rails' defaults, and additional PRAGMAs can be
910
+ set as well.
855
911
 
856
- * Remove deprecated `Tasks::DatabaseTasks.dump_filename`.
912
+ ```yaml
913
+ database: storage/development.sqlite3
914
+ timeout: 5000
915
+ pragmas:
916
+ journal_mode: off
917
+ temp_store: memory
918
+ ```
857
919
 
858
- *Rafael Mendonça França*
920
+ *Stephen Margheim*
859
921
 
860
- * Remove deprecated `Tasks::DatabaseTasks.schema_file`.
922
+ * Remove warning message when running SQLite in production, but leave it unconfigured.
861
923
 
862
- *Rafael Mendonça França*
924
+ There are valid use cases for running SQLite in production. However, it must be done
925
+ with care, so instead of a warning most users won't see anyway, it's preferable to
926
+ leave the configuration commented out to force them to think about having the database
927
+ on a persistent volume etc.
863
928
 
864
- * Remove deprecated `environment` and `name` arguments from `Tasks::DatabaseTasks.schema_up_to_date?`.
929
+ *Jacopo Beschi*, *Jean Boussier*
865
930
 
866
- *Rafael Mendonça França*
931
+ * Add support for generated columns to the SQLite3 adapter.
867
932
 
868
- * Merging conditions on the same column no longer maintain both conditions,
869
- and will be consistently replaced by the latter condition.
933
+ Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
934
+ This adds support for those to the SQLite3 adapter.
870
935
 
871
936
  ```ruby
872
- # Rails 6.1 (IN clause is replaced by merger side equality condition)
873
- Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
874
- # Rails 6.1 (both conflict conditions exists, deprecated)
875
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
876
- # Rails 6.1 with rewhere to migrate to Rails 7.0's behavior
877
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
878
- # Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
879
- Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
880
- Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
881
-
882
- *Rafael Mendonça França*
937
+ create_table :users do |t|
938
+ t.string :name
939
+ t.virtual :name_upper, type: :string, as: 'UPPER(name)'
940
+ t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
941
+ end
942
+ ```
883
943
 
884
- * Remove deprecated support to `Model.reorder(nil).first` to search using non-deterministic order.
944
+ *Stephen Margheim*
885
945
 
886
- *Rafael Mendonça França*
946
+ * TrilogyAdapter: ignore `host` if `socket` parameter is set.
887
947
 
888
- * Remove deprecated rake tasks:
948
+ This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
889
949
 
890
- * `db:schema:load_if_ruby`
891
- * `db:structure:dump`
892
- * `db:structure:load`
893
- * `db:structure:load_if_sql`
894
- * `db:structure:dump:#{name}`
895
- * `db:structure:load:#{name}`
896
- * `db:test:load_structure`
897
- * `db:test:load_structure:#{name}`
950
+ ```
951
+ DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
952
+ ```
898
953
 
899
- *Rafael Mendonça França*
954
+ *Jean Boussier*
900
955
 
901
- * Remove deprecated `DatabaseConfig#config` method.
956
+ * Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
957
+ `assert_no_queries_match` assertions public.
902
958
 
903
- *Rafael Mendonça França*
959
+ To assert the expected number of queries are made, Rails internally uses `assert_queries_count` and
960
+ `assert_no_queries`. To assert that specific SQL queries are made, `assert_queries_match` and
961
+ `assert_no_queries_match` are used. These assertions can now be used in applications as well.
904
962
 
905
- * Rollback transactions when the block returns earlier than expected.
963
+ ```ruby
964
+ class ArticleTest < ActiveSupport::TestCase
965
+ test "queries are made" do
966
+ assert_queries_count(1) { Article.first }
967
+ end
906
968
 
907
- Before this change, when a transaction block returned early, the transaction would be committed.
969
+ test "creates a foreign key" do
970
+ assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
971
+ @connection.add_foreign_key(:comments, :posts)
972
+ end
973
+ end
974
+ end
975
+ ```
908
976
 
909
- The problem is that timeouts triggered inside the transaction block was also making the incomplete transaction
910
- to be committed, so in order to avoid this mistake, the transaction block is rolled back.
977
+ *Petrik de Heus*, *fatkodima*
911
978
 
912
- *Rafael Mendonça França*
979
+ * Fix `has_secure_token` calls the setter method on initialize.
913
980
 
914
- * Add middleware for automatic shard swapping.
981
+ *Abeid Ahmed*
915
982
 
916
- Provides a basic middleware to perform automatic shard swapping. Applications will provide a resolver which will determine for an individual request which shard should be used. Example:
983
+ * When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
984
+ adapter. This allows decoupling the adapter the application chooses to use from the database connection details
985
+ set in the deployment environment.
917
986
 
918
987
  ```ruby
919
- config.active_record.shard_resolver = ->(request) {
920
- subdomain = request.subdomain
921
- tenant = Tenant.find_by_subdomain!(subdomain)
922
- tenant.shard
923
- }
988
+ # ENV['DATABASE_URL'] = "mysql://localhost/example_database"
989
+ config.active_record.protocol_adapters.mysql = "trilogy"
990
+ # will connect to MySQL using the trilogy adapter
924
991
  ```
925
992
 
926
- See guides for more details.
993
+ *Jean Boussier*, *Kevin McPhillips*
927
994
 
928
- *Eileen M. Uchitelle*, *John Crepezzi*
995
+ * In cases where MySQL returns `warning_count` greater than zero, but returns no warnings when
996
+ the `SHOW WARNINGS` query is executed, `ActiveRecord.db_warnings_action` proc will still be
997
+ called with a generic warning message rather than silently ignoring the warning(s).
929
998
 
930
- * Remove deprecated support to pass a column to `type_cast`.
999
+ *Kevin McPhillips*
931
1000
 
932
- *Rafael Mendonça França*
1001
+ * `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
933
1002
 
934
- * Remove deprecated support to type cast to database values `ActiveRecord::Base` objects.
1003
+ *Andrew Novoselac*
935
1004
 
936
- *Rafael Mendonça França*
937
-
938
- * Remove deprecated support to quote `ActiveRecord::Base` objects.
939
-
940
- *Rafael Mendonça França*
941
-
942
- * Remove deprecacated support to resolve connection using `"primary"` as connection specification name.
943
-
944
- *Rafael Mendonça França*
945
-
946
- * Remove deprecation warning when using `:interval` column is used in PostgreSQL database.
947
-
948
- Now, interval columns will return `ActiveSupport::Duration` objects instead of strings.
949
-
950
- To keep the old behavior, you can add this line to your model:
951
-
952
- ```ruby
953
- attribute :column, :string
954
- ```
955
-
956
- *Rafael Mendonça França*
957
-
958
- * Remove deprecated support to YAML load `ActiveRecord::Base` instance in the Rails 4.2 and 4.1 formats.
959
-
960
- *Rafael Mendonça França*
961
-
962
- * Remove deprecated option `:spec_name` in the `configs_for` method.
963
-
964
- *Rafael Mendonça França*
965
-
966
- * Remove deprecated `ActiveRecord::Base.allow_unsafe_raw_sql`.
967
-
968
- *Rafael Mendonça França*
969
-
970
- * Fix regression bug that caused ignoring additional conditions for preloading has_many-through relations.
971
-
972
- Fixes #43132
973
-
974
- *Alexander Pauly*
975
-
976
- * Fix `has_many` inversing recursion on models with recursive associations.
977
-
978
- *Gannon McGibbon*
979
-
980
- * Add `accepts_nested_attributes_for` support for `delegated_type`
981
-
982
- ```ruby
983
- class Entry < ApplicationRecord
984
- delegated_type :entryable, types: %w[ Message Comment ]
985
- accepts_nested_attributes_for :entryable
986
- end
987
-
988
- entry = Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
989
- # => #<Entry:0x00>
990
- # id: 1
991
- # entryable_id: 1,
992
- # entryable_type: 'Message'
993
- # ...>
994
-
995
- entry.entryable
996
- # => #<Message:0x01>
997
- # id: 1
998
- # content: 'Hello world'
999
- # ...>
1000
- ```
1001
-
1002
- Previously it would raise an error:
1003
-
1004
- ```ruby
1005
- Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
1006
- # ArgumentError: Cannot build association `entryable'. Are you trying to build a polymorphic one-to-one association?
1007
- ```
1008
-
1009
- *Sjors Baltus*
1010
-
1011
- * Use subquery for DELETE with GROUP_BY and HAVING clauses.
1012
-
1013
- Prior to this change, deletes with GROUP_BY and HAVING were returning an error.
1014
-
1015
- After this change, GROUP_BY and HAVING are valid clauses in DELETE queries, generating the following query:
1016
-
1017
- ```sql
1018
- DELETE FROM "posts" WHERE "posts"."id" IN (
1019
- SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."id" HAVING (count(comments.id) >= 2))
1020
- ) [["flagged", "t"]]
1021
- ```
1022
-
1023
- *Ignacio Chiazzo Cardarello*
1024
-
1025
- * Use subquery for UPDATE with GROUP_BY and HAVING clauses.
1026
-
1027
- Prior to this change, updates with GROUP_BY and HAVING were being ignored, generating a SQL like this:
1028
-
1029
- ```sql
1030
- UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
1031
- SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
1032
- ) [["flagged", "t"]]
1033
- ```
1034
-
1035
- After this change, GROUP_BY and HAVING clauses are used as a subquery in updates, like this:
1036
-
1037
- ```sql
1038
- UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
1039
- SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
1040
- GROUP BY posts.id HAVING (count(comments.id) >= 2)
1041
- ) [["flagged", "t"]]
1042
- ```
1043
-
1044
- *Ignacio Chiazzo Cardarello*
1045
-
1046
- * Add support for setting the filename of the schema or structure dump in the database config.
1047
-
1048
- Applications may now set their the filename or path of the schema / structure dump file in their database configuration.
1049
-
1050
- ```yaml
1051
- production:
1052
- primary:
1053
- database: my_db
1054
- schema_dump: my_schema_dump_filename.rb
1055
- animals:
1056
- database: animals_db
1057
- schema_dump: false
1058
- ```
1059
-
1060
- The filename set in `schema_dump` will be used by the application. If set to `false` the schema will not be dumped. The database tasks are responsible for adding the database directory to the filename. If a full path is provided, the Rails tasks will use that instead of `ActiveRecord::DatabaseTasks.db_dir`.
1061
-
1062
- *Eileen M. Uchitelle*, *Ryan Kerr*
1063
-
1064
- * Add `ActiveRecord::Base.prohibit_shard_swapping` to prevent attempts to change the shard within a block.
1065
-
1066
- *John Crepezzi*, *Eileen M. Uchitelle*
1067
-
1068
- * Filter unchanged attributes with default function from insert query when `partial_inserts` is disabled.
1069
-
1070
- *Akshay Birajdar*, *Jacopo Beschi*
1071
-
1072
- * Add support for FILTER clause (SQL:2003) to Arel.
1073
-
1074
- Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.
1075
-
1076
- *Andrey Novikov*
1077
-
1078
- * Automatically set timestamps on record creation during bulk insert/upsert
1079
-
1080
- Prior to this change, only updates during an upsert operation (e.g. `upsert_all`) would touch timestamps (`updated_{at,on}`). Now, record creations also touch timestamp columns (`{created,updated}_{at,on}`).
1081
-
1082
- This behaviour is controlled by the `<model>.record_timestamps` config, matching the behaviour of `create`, `update`, etc. It can also be overridden by using the `record_timestamps:` keyword argument.
1083
-
1084
- Note that this means `upsert_all` on models with `record_timestamps = false` will no longer touch `updated_{at,on}` automatically.
1085
-
1086
- *Sam Bostock*
1087
-
1088
- * Don't require `role` when passing `shard` to `connected_to`.
1089
-
1090
- `connected_to` can now be called with a `shard` only. Note that `role` is still inherited if `connected_to` calls are nested.
1091
-
1092
- *Eileen M. Uchitelle*
1093
-
1094
- * Add option to lazily load the schema cache on the connection.
1095
-
1096
- Previously, the only way to load the schema cache in Active Record was through the Railtie on boot. This option provides the ability to load the schema cache on the connection after it's been established. Loading the cache lazily on the connection can be beneficial for Rails applications that use multiple databases because it will load the cache at the time the connection is established. Currently Railties doesn't have access to the connections before boot.
1097
-
1098
- To use the cache, set `config.active_record.lazily_load_schema_cache = true` in your application configuration. In addition a `schema_cache_path` should be set in your database configuration if you don't want to use the default "db/schema_cache.yml" path.
1099
-
1100
- *Eileen M. Uchitelle*
1101
-
1102
- * Allow automatic `inverse_of` detection for associations with scopes.
1103
-
1104
- Automatic `inverse_of` detection now works for associations with scopes. For
1105
- example, the `comments` association here now automatically detects
1106
- `inverse_of: :post`, so we don't need to pass that option:
1107
-
1108
- ```ruby
1109
- class Post < ActiveRecord::Base
1110
- has_many :comments, -> { visible }
1111
- end
1112
-
1113
- class Comment < ActiveRecord::Base
1114
- belongs_to :post
1115
- end
1116
- ```
1117
-
1118
- Note that the automatic detection still won't work if the inverse
1119
- association has a scope. In this example a scope on the `post` association
1120
- would still prevent Rails from finding the inverse for the `comments`
1121
- association.
1122
-
1123
- This will be the default for new apps in Rails 7. To opt in:
1124
-
1125
- ```ruby
1126
- config.active_record.automatic_scope_inversing = true
1127
- ```
1128
-
1129
- *Daniel Colson*, *Chris Bloom*
1130
-
1131
- * Accept optional transaction args to `ActiveRecord::Locking::Pessimistic#with_lock`
1132
-
1133
- `#with_lock` now accepts transaction options like `requires_new:`,
1134
- `isolation:`, and `joinable:`
1135
-
1136
- *John Mileham*
1137
-
1138
- * Adds support for deferrable foreign key constraints in PostgreSQL.
1139
-
1140
- By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases,
1141
- but becomes a major limitation when creating related records before the parent record is inserted into the database.
1142
- One example of this is looking up / creating a person via one or more unique alias.
1143
-
1144
- ```ruby
1145
- Person.transaction do
1146
- alias = Alias
1147
- .create_with(user_id: SecureRandom.uuid)
1148
- .create_or_find_by(name: "DHH")
1149
-
1150
- person = Person
1151
- .create_with(name: "David Heinemeier Hansson")
1152
- .create_or_find_by(id: alias.user_id)
1153
- end
1154
- ```
1155
-
1156
- Using the default behavior, the transaction would fail when executing the first `INSERT` statement.
1157
-
1158
- By passing the `:deferrable` option to the `add_foreign_key` statement in migrations, it's possible to defer this
1159
- check.
1160
-
1161
- ```ruby
1162
- add_foreign_key :aliases, :person, deferrable: true
1163
- ```
1164
-
1165
- Passing `deferrable: true` doesn't change the default behavior, but allows manually deferring the check using
1166
- `SET CONSTRAINTS ALL DEFERRED` within a transaction. This will cause the foreign keys to be checked after the
1167
- transaction.
1168
-
1169
- It's also possible to adjust the default behavior from an immediate check (after the statement), to a deferred check
1170
- (after the transaction):
1171
-
1172
- ```ruby
1173
- add_foreign_key :aliases, :person, deferrable: :deferred
1174
- ```
1175
-
1176
- *Benedikt Deicke*
1177
-
1178
- * Allow configuring Postgres password through the socket URL.
1179
-
1180
- For example:
1181
- ```ruby
1182
- ActiveRecord::DatabaseConfigurations::UrlConfig.new(
1183
- :production, :production, 'postgres:///?user=user&password=secret&dbname=app', {}
1184
- ).configuration_hash
1185
- ```
1186
-
1187
- will now return,
1188
-
1189
- ```ruby
1190
- { :user=>"user", :password=>"secret", :dbname=>"app", :adapter=>"postgresql" }
1191
- ```
1192
-
1193
- *Abeid Ahmed*
1194
-
1195
- * PostgreSQL: support custom enum types
1196
-
1197
- In migrations, use `create_enum` to add a new enum type, and `t.enum` to add a column.
1198
-
1199
- ```ruby
1200
- def up
1201
- create_enum :mood, ["happy", "sad"]
1202
-
1203
- change_table :cats do |t|
1204
- t.enum :current_mood, enum_type: "mood", default: "happy", null: false
1205
- end
1206
- end
1207
- ```
1208
-
1209
- Enums will be presented correctly in `schema.rb`. Note that this is only supported by
1210
- the PostgreSQL adapter.
1211
-
1212
- *Alex Ghiculescu*
1213
-
1214
- * Avoid COMMENT statements in PostgreSQL structure dumps
1215
-
1216
- COMMENT statements are now omitted from the output of `db:structure:dump` when using PostgreSQL >= 11.
1217
- This allows loading the dump without a pgsql superuser account.
1218
-
1219
- Fixes #36816, #43107.
1220
-
1221
- *Janosch Müller*
1222
-
1223
- * Add support for generated columns in PostgreSQL adapter
1224
-
1225
- Generated columns are supported since version 12.0 of PostgreSQL. This adds
1226
- support of those to the PostgreSQL adapter.
1227
-
1228
- ```ruby
1229
- create_table :users do |t|
1230
- t.string :name
1231
- t.virtual :name_upcased, type: :string, as: 'upper(name)', stored: true
1232
- end
1233
- ```
1234
-
1235
- *Michał Begejowicz*
1236
-
1237
-
1238
- ## Rails 7.0.0.alpha2 (September 15, 2021) ##
1239
-
1240
- * No changes.
1241
-
1242
-
1243
- ## Rails 7.0.0.alpha1 (September 15, 2021) ##
1244
-
1245
- * Remove warning when overwriting existing scopes
1246
-
1247
- Removes the following unnecessary warning message that appeared when overwriting existing scopes
1248
-
1249
- ```
1250
- Creating scope :my_scope_name. Overwriting existing method "MyClass.my_scope_name" when overwriting existing scopes
1251
- ```
1252
-
1253
- *Weston Ganger*
1254
-
1255
- * Use full precision for `updated_at` in `insert_all`/`upsert_all`
1256
-
1257
- `CURRENT_TIMESTAMP` provides differing precision depending on the database,
1258
- and not all databases support explicitly specifying additional precision.
1259
-
1260
- Instead, we delegate to the new `connection.high_precision_current_timestamp`
1261
- for the SQL to produce a high precision timestamp on the current database.
1262
-
1263
- Fixes #42992
1264
-
1265
- *Sam Bostock*
1266
-
1267
- * Add ssl support for postgresql database tasks
1268
-
1269
- Add `PGSSLMODE`, `PGSSLCERT`, `PGSSLKEY` and `PGSSLROOTCERT` to pg_env from database config
1270
- when running postgresql database tasks.
1271
-
1272
- ```yaml
1273
- # config/database.yml
1274
-
1275
- production:
1276
- sslmode: verify-full
1277
- sslcert: client.crt
1278
- sslkey: client.key
1279
- sslrootcert: ca.crt
1280
- ```
1281
-
1282
- Environment variables
1283
-
1284
- ```
1285
- PGSSLMODE=verify-full
1286
- PGSSLCERT=client.crt
1287
- PGSSLKEY=client.key
1288
- PGSSLROOTCERT=ca.crt
1289
- ```
1290
-
1291
- Fixes #42994
1292
-
1293
- *Michael Bayucot*
1294
-
1295
- * Avoid scoping update callbacks in `ActiveRecord::Relation#update!`.
1296
-
1297
- Making it consistent with how scoping is applied only to the query in `ActiveRecord::Relation#update`
1298
- and not also to the callbacks from the update itself.
1299
-
1300
- *Dylan Thacker-Smith*
1301
-
1302
- * Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
1303
- using `String#constantize` instead of the model's `polymorphic_class_for`.
1304
-
1305
- When updating a polymorphic association, the old `foreign_type` was not inferred correctly when:
1306
- 1. `touch`ing the previously associated record
1307
- 2. updating the previously associated record's `counter_cache`
1308
-
1309
- *Jimmy Bourassa*
1310
-
1311
- * Add config option for ignoring tables when dumping the schema cache.
1312
-
1313
- Applications can now be configured to ignore certain tables when dumping the schema cache.
1314
-
1315
- The configuration option can table an array of tables:
1316
-
1317
- ```ruby
1318
- config.active_record.schema_cache_ignored_tables = ["ignored_table", "another_ignored_table"]
1319
- ```
1320
-
1321
- Or a regex:
1322
-
1323
- ```ruby
1324
- config.active_record.schema_cache_ignored_tables = [/^_/]
1325
- ```
1326
-
1327
- *Eileen M. Uchitelle*
1328
-
1329
- * Make schema cache methods return consistent results.
1330
-
1331
- Previously the schema cache methods `primary_keys`, `columns`, `columns_hash`, and `indexes`
1332
- would behave differently than one another when a table didn't exist and differently across
1333
- database adapters. This change unifies the behavior so each method behaves the same regardless
1334
- of adapter.
1335
-
1336
- The behavior now is:
1337
-
1338
- `columns`: (unchanged) raises a db error if the table does not exist.
1339
- `columns_hash`: (unchanged) raises a db error if the table does not exist.
1340
- `primary_keys`: (unchanged) returns `nil` if the table does not exist.
1341
- `indexes`: (changed for mysql2) returns `[]` if the table does not exist.
1342
-
1343
- *Eileen M. Uchitelle*
1344
-
1345
- * Reestablish connection to previous database after after running `db:schema:load:name`
1346
-
1347
- After running `db:schema:load:name` the previous connection is restored.
1348
-
1349
- *Jacopo Beschi*
1350
-
1351
- * Add database config option `database_tasks`
1352
-
1353
- If you would like to connect to an external database without any database
1354
- management tasks such as schema management, migrations, seeds, etc. you can set
1355
- the per database config option `database_tasks: false`
1356
-
1357
- ```yaml
1358
- # config/database.yml
1359
-
1360
- production:
1361
- primary:
1362
- database: my_database
1363
- adapter: mysql2
1364
- animals:
1365
- database: my_animals_database
1366
- adapter: mysql2
1367
- database_tasks: false
1368
- ```
1369
-
1370
- *Weston Ganger*
1371
-
1372
- * Fix `ActiveRecord::InternalMetadata` to not be broken by `config.active_record.record_timestamps = false`
1373
-
1374
- Since the model always create the timestamp columns, it has to set them, otherwise it breaks
1375
- various DB management tasks.
1376
-
1377
- Fixes #42983
1378
-
1379
- * Add `ActiveRecord::QueryLogs`.
1380
-
1381
- Configurable tags can be automatically added to all SQL queries generated by Active Record.
1382
-
1383
- ```ruby
1384
- # config/application.rb
1385
- module MyApp
1386
- class Application < Rails::Application
1387
- config.active_record.query_log_tags_enabled = true
1388
- end
1389
- end
1390
- ```
1391
-
1392
- By default the application, controller and action details are added to the query tags:
1393
-
1394
- ```ruby
1395
- class BooksController < ApplicationController
1396
- def index
1397
- @books = Book.all
1398
- end
1399
- end
1400
- ```
1401
-
1402
- ```ruby
1403
- GET /books
1404
- # SELECT * FROM books /*application:MyApp;controller:books;action:index*/
1405
- ```
1406
-
1407
- Custom tags containing static values and Procs can be defined in the application configuration:
1408
-
1409
- ```ruby
1410
- config.active_record.query_log_tags = [
1411
- :application,
1412
- :controller,
1413
- :action,
1414
- {
1415
- custom_static: "foo",
1416
- custom_dynamic: -> { Time.now }
1417
- }
1418
- ]
1419
- ```
1420
-
1421
- *Keeran Raj Hawoldar*, *Eileen M. Uchitelle*, *Kasper Timm Hansen*
1422
-
1423
- * Added support for multiple databases to `rails db:setup` and `rails db:reset`.
1424
-
1425
- *Ryan Hall*
1426
-
1427
- * Add `ActiveRecord::Relation#structurally_compatible?`.
1428
-
1429
- Adds a query method by which a user can tell if the relation that they're
1430
- about to use for `#or` or `#and` is structurally compatible with the
1431
- receiver.
1432
-
1433
- *Kevin Newton*
1434
-
1435
- * Add `ActiveRecord::QueryMethods#in_order_of`.
1436
-
1437
- This allows you to specify an explicit order that you'd like records
1438
- returned in based on a SQL expression. By default, this will be accomplished
1439
- using a case statement, as in:
1440
-
1441
- ```ruby
1442
- Post.in_order_of(:id, [3, 5, 1])
1443
- ```
1444
-
1445
- will generate the SQL:
1446
-
1447
- ```sql
1448
- SELECT "posts".* FROM "posts" ORDER BY CASE "posts"."id" WHEN 3 THEN 1 WHEN 5 THEN 2 WHEN 1 THEN 3 ELSE 4 END ASC
1449
- ```
1450
-
1451
- However, because this functionality is built into MySQL in the form of the
1452
- `FIELD` function, that connection adapter will generate the following SQL
1453
- instead:
1454
-
1455
- ```sql
1456
- SELECT "posts".* FROM "posts" ORDER BY FIELD("posts"."id", 1, 5, 3) DESC
1457
- ```
1458
-
1459
- *Kevin Newton*
1460
-
1461
- * Fix `eager_loading?` when ordering with `Symbol`.
1462
-
1463
- `eager_loading?` is triggered correctly when using `order` with symbols.
1464
-
1465
- ```ruby
1466
- scope = Post.includes(:comments).order(:"comments.label")
1467
- => true
1468
- ```
1469
-
1470
- *Jacopo Beschi*
1471
-
1472
- * Two change tracking methods are added for `belongs_to` associations.
1473
-
1474
- The `association_changed?` method (assuming an association named `:association`) returns true
1475
- if a different associated object has been assigned and the foreign key will be updated in the
1476
- next save.
1477
-
1478
- The `association_previously_changed?` method returns true if the previous save updated the
1479
- association to reference a different associated object.
1480
-
1481
- *George Claghorn*
1482
-
1483
- * Add option to disable schema dump per-database.
1484
-
1485
- Dumping the schema is on by default for all databases in an application. To turn it off for a
1486
- specific database, use the `schema_dump` option:
1487
-
1488
- ```yaml
1489
- # config/database.yml
1490
-
1491
- production:
1492
- schema_dump: false
1493
- ```
1494
-
1495
- *Luis Vasconcellos*, *Eileen M. Uchitelle*
1496
-
1497
- * Fix `eager_loading?` when ordering with `Hash` syntax.
1498
-
1499
- `eager_loading?` is triggered correctly when using `order` with hash syntax
1500
- on an outer table.
1501
-
1502
- ```ruby
1503
- Post.includes(:comments).order({ "comments.label": :ASC }).eager_loading?
1504
- # => true
1505
- ```
1506
-
1507
- *Jacopo Beschi*
1508
-
1509
- * Move the forcing of clear text encoding to the `ActiveRecord::Encryption::Encryptor`.
1510
-
1511
- Fixes #42699.
1512
-
1513
- *J Smith*
1514
-
1515
- * `partial_inserts` is now disabled by default in new apps.
1516
-
1517
- This will be the default for new apps in Rails 7. To opt in:
1518
-
1519
- ```ruby
1520
- config.active_record.partial_inserts = true
1521
- ```
1522
-
1523
- If a migration removes the default value of a column, this option
1524
- would cause old processes to no longer be able to create new records.
1525
-
1526
- If you need to remove a column, you should first use `ignored_columns`
1527
- to stop using it.
1528
-
1529
- *Jean Boussier*
1530
-
1531
- * Rails can now verify foreign keys after loading fixtures in tests.
1532
-
1533
- This will be the default for new apps in Rails 7. To opt in:
1534
-
1535
- ```ruby
1536
- config.active_record.verify_foreign_keys_for_fixtures = true
1537
- ```
1538
-
1539
- Tests will not run if there is a foreign key constraint violation in your fixture data.
1540
-
1541
- The feature is supported by SQLite and PostgreSQL, other adapters can also add support for it.
1542
-
1543
- *Alex Ghiculescu*
1544
-
1545
- * Clear cached `has_one` association after setting `belongs_to` association to `nil`.
1546
-
1547
- After setting a `belongs_to` relation to `nil` and updating an unrelated attribute on the owner,
1548
- the owner should still return `nil` on the `has_one` relation.
1549
-
1550
- Fixes #42597.
1551
-
1552
- *Michiel de Mare*
1553
-
1554
- * OpenSSL constants are now used for Digest computations.
1555
-
1556
- *Dirkjan Bussink*
1557
-
1558
- * Adds support for `if_not_exists` to `add_foreign_key` and `if_exists` to `remove_foreign_key`.
1559
-
1560
- Applications can set their migrations to ignore exceptions raised when adding a foreign key
1561
- that already exists or when removing a foreign key that does not exist.
1562
-
1563
- Example Usage:
1564
-
1565
- ```ruby
1566
- class AddAuthorsForeignKeyToArticles < ActiveRecord::Migration[7.0]
1567
- def change
1568
- add_foreign_key :articles, :authors, if_not_exists: true
1569
- end
1570
- end
1571
- ```
1572
-
1573
- ```ruby
1574
- class RemoveAuthorsForeignKeyFromArticles < ActiveRecord::Migration[7.0]
1575
- def change
1576
- remove_foreign_key :articles, :authors, if_exists: true
1577
- end
1578
- end
1579
- ```
1580
-
1581
- *Roberto Miranda*
1582
-
1583
- * Prevent polluting ENV during postgresql structure dump/load.
1584
-
1585
- Some configuration parameters were provided to pg_dump / psql via
1586
- environment variables which persisted beyond the command being run, and may
1587
- have caused subsequent commands and connections to fail. Tasks running
1588
- across multiple postgresql databases like `rails db:test:prepare` may have
1589
- been affected.
1590
-
1591
- *Samuel Cochran*
1592
-
1593
- * Set precision 6 by default for `datetime` columns.
1594
-
1595
- By default, datetime columns will have microseconds precision instead of seconds precision.
1596
-
1597
- *Roberto Miranda*
1598
-
1599
- * Allow preloading of associations with instance dependent scopes.
1600
-
1601
- *John Hawthorn*, *John Crepezzi*, *Adam Hess*, *Eileen M. Uchitelle*, *Dinah Shi*
1602
-
1603
- * Do not try to rollback transactions that failed due to a `ActiveRecord::TransactionRollbackError`.
1604
-
1605
- *Jamie McCarthy*
1606
-
1607
- * Active Record Encryption will now encode values as UTF-8 when using deterministic
1608
- encryption. The encoding is part of the encrypted payload, so different encodings for
1609
- different values result in different ciphertexts. This can break unique constraints and
1610
- queries.
1611
-
1612
- The new behavior is configurable via `active_record.encryption.forced_encoding_for_deterministic_encryption`
1613
- that is `Encoding::UTF_8` by default. It can be disabled by setting it to `nil`.
1614
-
1615
- *Jorge Manrubia*
1616
-
1617
- * The MySQL adapter now cast numbers and booleans bind parameters to string for safety reasons.
1618
-
1619
- When comparing a string and a number in a query, MySQL converts the string to a number. So for
1620
- instance `"foo" = 0`, will implicitly cast `"foo"` to `0` and will evaluate to `TRUE` which can
1621
- lead to security vulnerabilities.
1622
-
1623
- Active Record already protect against that vulnerability when it knows the type of the column
1624
- being compared, however until now it was still vulnerable when using bind parameters:
1625
-
1626
- ```ruby
1627
- User.where("login_token = ?", 0).first
1628
- ```
1629
-
1630
- Would perform:
1631
-
1632
- ```sql
1633
- SELECT * FROM `users` WHERE `login_token` = 0 LIMIT 1;
1634
- ```
1635
-
1636
- Now it will perform:
1637
-
1638
- ```sql
1639
- SELECT * FROM `users` WHERE `login_token` = '0' LIMIT 1;
1640
- ```
1641
-
1642
- *Jean Boussier*
1643
-
1644
- * Fixture configurations (`_fixture`) are now strictly validated.
1645
-
1646
- If an error will be raised if that entry contains unknown keys while previously it
1647
- would silently have no effects.
1648
-
1649
- *Jean Boussier*
1650
-
1651
- * Add `ActiveRecord::Base.update!` that works like `ActiveRecord::Base.update` but raises exceptions.
1652
-
1653
- This allows for the same behavior as the instance method `#update!` at a class level.
1654
-
1655
- ```ruby
1656
- Person.update!(:all, state: "confirmed")
1657
- ```
1658
-
1659
- *Dorian Marié*
1660
-
1661
- * Add `ActiveRecord::Base#attributes_for_database`.
1662
-
1663
- Returns attributes with values for assignment to the database.
1664
-
1665
- *Chris Salzberg*
1666
-
1667
- * Use an empty query to check if the PostgreSQL connection is still active.
1668
-
1669
- An empty query is faster than `SELECT 1`.
1670
-
1671
- *Heinrich Lee Yu*
1672
-
1673
- * Add `ActiveRecord::Base#previously_persisted?`.
1674
-
1675
- Returns `true` if the object has been previously persisted but now it has been deleted.
1676
-
1677
- * Deprecate `partial_writes` in favor of `partial_inserts` and `partial_updates`.
1678
-
1679
- This allows to have a different behavior on update and create.
1680
-
1681
- *Jean Boussier*
1682
-
1683
- * Fix compatibility with `psych >= 4`.
1684
-
1685
- Starting in Psych 4.0.0 `YAML.load` behaves like `YAML.safe_load`. To preserve compatibility,
1686
- Active Record's schema cache loader and `YAMLColumn` now uses `YAML.unsafe_load` if available.
1687
-
1688
- *Jean Boussier*
1689
-
1690
- * `ActiveRecord::Base.logger` is now a `class_attribute`.
1691
-
1692
- This means it can no longer be accessed directly through `@@logger`, and that setting `logger =`
1693
- on a subclass won't change the parent's logger.
1694
-
1695
- *Jean Boussier*
1696
-
1697
- * Add `.asc.nulls_first` for all databases. Unfortunately MySQL still doesn't like `nulls_last`.
1698
-
1699
- *Keenan Brock*
1700
-
1701
- * Improve performance of `one?` and `many?` by limiting the generated count query to 2 results.
1702
-
1703
- *Gonzalo Riestra*
1704
-
1705
- * Don't check type when using `if_not_exists` on `add_column`.
1706
-
1707
- Previously, if a migration called `add_column` with the `if_not_exists` option set to true
1708
- the `column_exists?` check would look for a column with the same name and type as the migration.
1709
-
1710
- Recently it was discovered that the type passed to the migration is not always the same type
1711
- as the column after migration. For example a column set to `:mediumblob` in the migration will
1712
- be casted to `binary` when calling `column.type`. Since there is no straightforward way to cast
1713
- the type to the database type without running the migration, we opted to drop the type check from
1714
- `add_column`. This means that migrations adding a duplicate column with a different type will no
1715
- longer raise an error.
1716
-
1717
- *Eileen M. Uchitelle*
1718
-
1719
- * Log a warning message when running SQLite in production.
1720
-
1721
- Using SQLite in production ENV is generally discouraged. SQLite is also the default adapter
1722
- in a new Rails application.
1723
- For the above reasons log a warning message when running SQLite in production.
1724
-
1725
- The warning can be disabled by setting `config.active_record.sqlite3_production_warning=false`.
1726
-
1727
- *Jacopo Beschi*
1728
-
1729
- * Add option to disable joins for `has_one` associations.
1730
-
1731
- In a multiple database application, associations can't join across
1732
- databases. When set, this option instructs Rails to generate 2 or
1733
- more queries rather than generating joins for `has_one` associations.
1734
-
1735
- Set the option on a has one through association:
1736
-
1737
- ```ruby
1738
- class Person
1739
- has_one :dog
1740
- has_one :veterinarian, through: :dog, disable_joins: true
1741
- end
1742
- ```
1005
+ * Fix `where(field: values)` queries when `field` is a serialized attribute
1006
+ (for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
1007
+ column).
1743
1008
 
1744
- Then instead of generating join SQL, two queries are used for `@person.veterinarian`:
1009
+ *João Alves*
1745
1010
 
1746
- ```
1747
- SELECT "dogs"."id" FROM "dogs" WHERE "dogs"."person_id" = ? [["person_id", 1]]
1748
- SELECT "veterinarians".* FROM "veterinarians" WHERE "veterinarians"."dog_id" = ? [["dog_id", 1]]
1749
- ```
1750
-
1751
- *Sarah Vessels*, *Eileen M. Uchitelle*
1752
-
1753
- * `Arel::Visitors::Dot` now renders a complete set of properties when visiting
1754
- `Arel::Nodes::SelectCore`, `SelectStatement`, `InsertStatement`, `UpdateStatement`, and
1755
- `DeleteStatement`, which fixes #42026. Previously, some properties were omitted.
1756
-
1757
- *Mike Dalessio*
1758
-
1759
- * `Arel::Visitors::Dot` now supports `Arel::Nodes::Bin`, `Case`, `CurrentRow`, `Distinct`,
1760
- `DistinctOn`, `Else`, `Except`, `InfixOperation`, `Intersect`, `Lock`, `NotRegexp`, `Quoted`,
1761
- `Regexp`, `UnaryOperation`, `Union`, `UnionAll`, `When`, and `With`. Previously, these node
1762
- types caused an exception to be raised by `Arel::Visitors::Dot#accept`.
1763
-
1764
- *Mike Dalessio*
1765
-
1766
- * Optimize `remove_columns` to use a single SQL statement.
1767
-
1768
- ```ruby
1769
- remove_columns :my_table, :col_one, :col_two
1770
- ```
1771
-
1772
- Now results in the following SQL:
1773
-
1774
- ```sql
1775
- ALTER TABLE "my_table" DROP COLUMN "col_one", DROP COLUMN "col_two"
1776
- ```
1777
-
1778
- *Jon Dufresne*
1779
-
1780
- * Ensure `has_one` autosave association callbacks get called once.
1781
-
1782
- Change the `has_one` autosave callback to be non cyclic as well.
1783
- By doing this the autosave callback are made more consistent for
1784
- all 3 cases: `has_many`, `has_one`, and `belongs_to`.
1785
-
1786
- *Petrik de Heus*
1787
-
1788
- * Add option to disable joins for associations.
1789
-
1790
- In a multiple database application, associations can't join across
1791
- databases. When set, this option instructs Rails to generate 2 or
1792
- more queries rather than generating joins for associations.
1793
-
1794
- Set the option on a has many through association:
1795
-
1796
- ```ruby
1797
- class Dog
1798
- has_many :treats, through: :humans, disable_joins: true
1799
- has_many :humans
1800
- end
1801
- ```
1802
-
1803
- Then instead of generating join SQL, two queries are used for `@dog.treats`:
1804
-
1805
- ```
1806
- SELECT "humans"."id" FROM "humans" WHERE "humans"."dog_id" = ? [["dog_id", 1]]
1807
- SELECT "treats".* FROM "treats" WHERE "treats"."human_id" IN (?, ?, ?) [["human_id", 1], ["human_id", 2], ["human_id", 3]]
1808
- ```
1809
-
1810
- *Eileen M. Uchitelle*, *Aaron Patterson*, *Lee Quarella*
1811
-
1812
- * Add setting for enumerating column names in SELECT statements.
1813
-
1814
- Adding a column to a PostgreSQL database, for example, while the application is running can
1815
- change the result of wildcard `SELECT *` queries, which invalidates the result
1816
- of cached prepared statements and raises a `PreparedStatementCacheExpired` error.
1817
-
1818
- When enabled, Active Record will avoid wildcards and always include column names
1819
- in `SELECT` queries, which will return consistent results and avoid prepared
1820
- statement errors.
1821
-
1822
- Before:
1823
-
1824
- ```ruby
1825
- Book.limit(5)
1826
- # SELECT * FROM books LIMIT 5
1827
- ```
1828
-
1829
- After:
1830
-
1831
- ```ruby
1832
- # config/application.rb
1833
- module MyApp
1834
- class Application < Rails::Application
1835
- config.active_record.enumerate_columns_in_select_statements = true
1836
- end
1837
- end
1838
-
1839
- # or, configure per-model
1840
- class Book < ApplicationRecord
1841
- self.enumerate_columns_in_select_statements = true
1842
- end
1843
- ```
1844
-
1845
- ```ruby
1846
- Book.limit(5)
1847
- # SELECT id, author_id, name, format, status, language, etc FROM books LIMIT 5
1848
- ```
1849
-
1850
- *Matt Duszynski*
1851
-
1852
- * Allow passing SQL as `on_duplicate` value to `#upsert_all` to make it possible to use raw SQL to update columns on conflict:
1853
-
1854
- ```ruby
1855
- Book.upsert_all(
1856
- [{ id: 1, status: 1 }, { id: 2, status: 1 }],
1857
- on_duplicate: Arel.sql("status = GREATEST(books.status, EXCLUDED.status)")
1858
- )
1859
- ```
1860
-
1861
- *Vladimir Dementyev*
1862
-
1863
- * Allow passing SQL as `returning` statement to `#upsert_all`:
1864
-
1865
- ```ruby
1866
- Article.insert_all(
1867
- [
1868
- { title: "Article 1", slug: "article-1", published: false },
1869
- { title: "Article 2", slug: "article-2", published: false }
1870
- ],
1871
- returning: Arel.sql("id, (xmax = '0') as inserted, name as new_name")
1872
- )
1873
- ```
1874
-
1875
- *Vladimir Dementyev*
1876
-
1877
- * Deprecate `legacy_connection_handling`.
1878
-
1879
- *Eileen M. Uchitelle*
1880
-
1881
- * Add attribute encryption support.
1882
-
1883
- Encrypted attributes are declared at the model level. These
1884
- are regular Active Record attributes backed by a column with
1885
- the same name. The system will transparently encrypt these
1886
- attributes before saving them into the database and will
1887
- decrypt them when retrieving their values.
1888
-
1889
-
1890
- ```ruby
1891
- class Person < ApplicationRecord
1892
- encrypts :name
1893
- encrypts :email_address, deterministic: true
1894
- end
1895
- ```
1896
-
1897
- You can learn more in the [Active Record Encryption
1898
- guide](https://edgeguides.rubyonrails.org/active_record_encryption.html).
1899
-
1900
- *Jorge Manrubia*
1901
-
1902
- * Changed Arel predications `contains` and `overlaps` to use
1903
- `quoted_node` so that PostgreSQL arrays are quoted properly.
1904
-
1905
- *Bradley Priest*
1906
-
1907
- * Add mode argument to record level `strict_loading!`.
1908
-
1909
- This argument can be used when enabling strict loading for a single record
1910
- to specify that we only want to raise on n plus one queries.
1911
-
1912
- ```ruby
1913
- developer.strict_loading!(mode: :n_plus_one_only)
1914
-
1915
- developer.projects.to_a # Does not raise
1916
- developer.projects.first.client # Raises StrictLoadingViolationError
1917
- ```
1918
-
1919
- Previously, enabling strict loading would cause any lazily loaded
1920
- association to raise an error. Using `n_plus_one_only` mode allows us to
1921
- lazily load belongs_to, has_many, and other associations that are fetched
1922
- through a single query.
1923
-
1924
- *Dinah Shi*
1925
-
1926
- * Fix Float::INFINITY assignment to datetime column with postgresql adapter.
1927
-
1928
- Before:
1929
-
1930
- ```ruby
1931
- # With this config
1932
- ActiveRecord::Base.time_zone_aware_attributes = true
1933
-
1934
- # and the following schema:
1935
- create_table "postgresql_infinities" do |t|
1936
- t.datetime "datetime"
1937
- end
1938
-
1939
- # This test fails
1940
- record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
1941
- assert_equal Float::INFINITY, record.datetime # record.datetime gets nil
1942
- ```
1943
-
1944
- After this commit, `record.datetime` gets `Float::INFINITY` as expected.
1945
-
1946
- *Shunichi Ikegami*
1947
-
1948
- * Type cast enum values by the original attribute type.
1949
-
1950
- The notable thing about this change is that unknown labels will no longer match 0 on MySQL.
1951
-
1952
- ```ruby
1953
- class Book < ActiveRecord::Base
1954
- enum :status, { proposed: 0, written: 1, published: 2 }
1955
- end
1956
- ```
1957
-
1958
- Before:
1959
-
1960
- ```ruby
1961
- # SELECT `books`.* FROM `books` WHERE `books`.`status` = 'prohibited' LIMIT 1
1962
- Book.find_by(status: :prohibited)
1963
- # => #<Book id: 1, status: "proposed", ...> (for mysql2 adapter)
1964
- # => ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: invalid input syntax for type integer: "prohibited" (for postgresql adapter)
1965
- # => nil (for sqlite3 adapter)
1966
- ```
1967
-
1968
- After:
1969
-
1970
- ```ruby
1971
- # SELECT `books`.* FROM `books` WHERE `books`.`status` IS NULL LIMIT 1
1972
- Book.find_by(status: :prohibited)
1973
- # => nil (for all adapters)
1974
- ```
1975
-
1976
- *Ryuta Kamizono*
1977
-
1978
- * Fixtures for `has_many :through` associations now load timestamps on join tables.
1979
-
1980
- Given this fixture:
1981
-
1982
- ```yml
1983
- ### monkeys.yml
1984
- george:
1985
- name: George the Monkey
1986
- fruits: apple
1987
-
1988
- ### fruits.yml
1989
- apple:
1990
- name: apple
1991
- ```
1992
-
1993
- If the join table (`fruit_monkeys`) contains `created_at` or `updated_at` columns,
1994
- these will now be populated when loading the fixture. Previously, fixture loading
1995
- would crash if these columns were required, and leave them as null otherwise.
1996
-
1997
- *Alex Ghiculescu*
1998
-
1999
- * Allow applications to configure the thread pool for async queries.
2000
-
2001
- Some applications may want one thread pool per database whereas others want to use
2002
- a single global thread pool for all queries. By default, Rails will set `async_query_executor`
2003
- to `nil` which will not initialize any executor. If `load_async` is called and no executor
2004
- has been configured, the query will be executed in the foreground.
2005
-
2006
- To create one thread pool for all database connections to use applications can set
2007
- `config.active_record.async_query_executor` to `:global_thread_pool` and optionally define
2008
- `config.active_record.global_executor_concurrency`. This defaults to 4. For applications that want
2009
- to have a thread pool for each database connection, `config.active_record.async_query_executor` can
2010
- be set to `:multi_thread_pool`. The configuration for each thread pool is set in the database
2011
- configuration.
2012
-
2013
- *Eileen M. Uchitelle*
2014
-
2015
- * Allow new syntax for `enum` to avoid leading `_` from reserved options.
1011
+ * Make the output of `ActiveRecord::Core#inspect` configurable.
2016
1012
 
2017
- Before:
2018
-
2019
- ```ruby
2020
- class Book < ActiveRecord::Base
2021
- enum status: [ :proposed, :written ], _prefix: true, _scopes: false
2022
- enum cover: [ :hard, :soft ], _suffix: true, _default: :hard
2023
- end
2024
- ```
2025
-
2026
- After:
2027
-
2028
- ```ruby
2029
- class Book < ActiveRecord::Base
2030
- enum :status, [ :proposed, :written ], prefix: true, scopes: false
2031
- enum :cover, [ :hard, :soft ], suffix: true, default: :hard
2032
- end
2033
- ```
2034
-
2035
- *Ryuta Kamizono*
2036
-
2037
- * Add `ActiveRecord::Relation#load_async`.
2038
-
2039
- This method schedules the query to be performed asynchronously from a thread pool.
2040
-
2041
- If the result is accessed before a background thread had the opportunity to perform
2042
- the query, it will be performed in the foreground.
2043
-
2044
- This is useful for queries that can be performed long enough before their result will be
2045
- needed, or for controllers which need to perform several independent queries.
2046
-
2047
- ```ruby
2048
- def index
2049
- @categories = Category.some_complex_scope.load_async
2050
- @posts = Post.some_complex_scope.load_async
2051
- end
2052
- ```
2053
-
2054
- Active Record logs will also include timing info for the duration of how long
2055
- the main thread had to wait to access the result. This timing is useful to know
2056
- whether or not it's worth to load the query asynchronously.
2057
-
2058
- ```
2059
- DEBUG -- : Category Load (62.1ms) SELECT * FROM `categories` LIMIT 50
2060
- DEBUG -- : ASYNC Post Load (64ms) (db time 126.1ms) SELECT * FROM `posts` LIMIT 100
2061
- ```
2062
-
2063
- The duration in the first set of parens is how long the main thread was blocked
2064
- waiting for the results, and the second set of parens with "db time" is how long
2065
- the entire query took to execute.
2066
-
2067
- *Jean Boussier*
2068
-
2069
- * Implemented `ActiveRecord::Relation#excluding` method.
2070
-
2071
- This method excludes the specified record (or collection of records) from
2072
- the resulting relation:
2073
-
2074
- ```ruby
2075
- Post.excluding(post)
2076
- Post.excluding(post_one, post_two)
2077
- ```
2078
-
2079
- Also works on associations:
2080
-
2081
- ```ruby
2082
- post.comments.excluding(comment)
2083
- post.comments.excluding(comment_one, comment_two)
2084
- ```
2085
-
2086
- This is short-hand for `Post.where.not(id: post.id)` (for a single record)
2087
- and `Post.where.not(id: [post_one.id, post_two.id])` (for a collection).
2088
-
2089
- *Glen Crawford*
2090
-
2091
- * Skip optimised #exist? query when #include? is called on a relation
2092
- with a having clause.
2093
-
2094
- Relations that have aliased select values AND a having clause that
2095
- references an aliased select value would generate an error when
2096
- #include? was called, due to an optimisation that would generate
2097
- call #exists? on the relation instead, which effectively alters
2098
- the select values of the query (and thus removes the aliased select
2099
- values), but leaves the having clause intact. Because the having
2100
- clause is then referencing an aliased column that is no longer
2101
- present in the simplified query, an ActiveRecord::InvalidStatement
2102
- error was raised.
2103
-
2104
- A sample query affected by this problem:
2105
-
2106
- ```ruby
2107
- Author.select('COUNT(*) as total_posts', 'authors.*')
2108
- .joins(:posts)
2109
- .group(:id)
2110
- .having('total_posts > 2')
2111
- .include?(Author.first)
2112
- ```
2113
-
2114
- This change adds an addition check to the condition that skips the
2115
- simplified #exists? query, which simply checks for the presence of
2116
- a having clause.
2117
-
2118
- Fixes #41417.
2119
-
2120
- *Michael Smart*
2121
-
2122
- * Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
2123
- without Rails knowledge (e.g., if app gets killed during long-running query or due to Rack::Timeout), app won't end
2124
- up in perpetual crash state for being inconsistent with PostgreSQL.
2125
-
2126
- *wbharding*, *Martin Tepper*
2127
-
2128
- * Add ability to apply `scoping` to `all_queries`.
2129
-
2130
- Some applications may want to use the `scoping` method but previously it only
2131
- worked on certain types of queries. This change allows the `scoping` method to apply
2132
- to all queries for a model in a block.
2133
-
2134
- ```ruby
2135
- Post.where(blog_id: post.blog_id).scoping(all_queries: true) do
2136
- post.update(title: "a post title") # adds `posts.blog_id = 1` to the query
2137
- end
2138
- ```
2139
-
2140
- *Eileen M. Uchitelle*
2141
-
2142
- * `ActiveRecord::Calculations.calculate` called with `:average`
2143
- (aliased as `ActiveRecord::Calculations.average`) will now use column-based
2144
- type casting. This means that floating-point number columns will now be
2145
- aggregated as `Float` and decimal columns will be aggregated as `BigDecimal`.
2146
-
2147
- Integers are handled as a special case returning `BigDecimal` always
2148
- (this was the case before already).
2149
-
2150
- ```ruby
2151
- # With the following schema:
2152
- create_table "measurements" do |t|
2153
- t.float "temperature"
2154
- end
2155
-
2156
- # Before:
2157
- Measurement.average(:temperature).class
2158
- # => BigDecimal
2159
-
2160
- # After:
2161
- Measurement.average(:temperature).class
2162
- # => Float
2163
- ```
2164
-
2165
- Before this change, Rails just called `to_d` on average aggregates from the
2166
- database adapter. This is not the case anymore. If you relied on that kind
2167
- of magic, you now need to register your own `ActiveRecord::Type`
2168
- (see `ActiveRecord::Attributes::ClassMethods` for documentation).
2169
-
2170
- *Josua Schmid*
2171
-
2172
- * PostgreSQL: introduce `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`.
2173
-
2174
- This setting controls what native type Active Record should use when you call `datetime` in
2175
- a migration or schema. It takes a symbol which must correspond to one of the configured
2176
- `NATIVE_DATABASE_TYPES`. The default is `:timestamp`, meaning `t.datetime` in a migration
2177
- will create a "timestamp without time zone" column. To use "timestamp with time zone",
2178
- change this to `:timestamptz` in an initializer.
2179
-
2180
- You should run `bin/rails db:migrate` to rebuild your schema.rb if you change this.
2181
-
2182
- *Alex Ghiculescu*
2183
-
2184
- * PostgreSQL: handle `timestamp with time zone` columns correctly in `schema.rb`.
2185
-
2186
- Previously they dumped as `t.datetime :column_name`, now they dump as `t.timestamptz :column_name`,
2187
- and are created as `timestamptz` columns when the schema is loaded.
2188
-
2189
- *Alex Ghiculescu*
2190
-
2191
- * Removing trailing whitespace when matching columns in
2192
- `ActiveRecord::Sanitization.disallow_raw_sql!`.
2193
-
2194
- *Gannon McGibbon*, *Adrian Hirt*
2195
-
2196
- * Expose a way for applications to set a `primary_abstract_class`.
2197
-
2198
- Multiple database applications that use a primary abstract class that is not
2199
- named `ApplicationRecord` can now set a specific class to be the `primary_abstract_class`.
1013
+ By default, calling `inspect` on a record will yield a formatted string including just the `id`.
2200
1014
 
2201
1015
  ```ruby
2202
- class PrimaryApplicationRecord
2203
- self.primary_abstract_class
2204
- end
1016
+ Post.first.inspect #=> "#<Post id: 1>"
2205
1017
  ```
2206
1018
 
2207
- When an application boots it automatically connects to the primary or first database in the
2208
- database configuration file. In a multiple database application that then call `connects_to`
2209
- needs to know that the default connection is the same as the `ApplicationRecord` connection.
2210
- However, some applications have a differently named `ApplicationRecord`. This prevents Active
2211
- Record from opening duplicate connections to the same database.
2212
-
2213
- *Eileen M. Uchitelle*, *John Crepezzi*
2214
-
2215
- * Support hash config for `structure_dump_flags` and `structure_load_flags` flags.
2216
- Now that Active Record supports multiple databases configuration,
2217
- we need a way to pass specific flags for dump/load databases since
2218
- the options are not the same for different adapters.
2219
- We can use in the original way:
1019
+ The attributes to be included in the output of `inspect` can be configured with
1020
+ `ActiveRecord::Core#attributes_for_inspect`.
2220
1021
 
2221
1022
  ```ruby
2222
- ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-defaults', '--skip-add-drop-table']
2223
- # or
2224
- ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table'
1023
+ Post.attributes_for_inspect = [:id, :title]
1024
+ Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
2225
1025
  ```
2226
1026
 
2227
- And also use it passing a hash, with one or more keys, where the key
2228
- is the adapter
1027
+ With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
2229
1028
 
2230
1029
  ```ruby
2231
- ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
2232
- mysql2: ['--no-defaults', '--skip-add-drop-table'],
2233
- postgres: '--no-tablespaces'
2234
- }
1030
+ Post.attributes_for_inspect = :all
1031
+ Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
2235
1032
  ```
2236
1033
 
2237
- *Gustavo Gonzalez*
1034
+ In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
2238
1035
 
2239
- * Connection specification now passes the "url" key as a configuration for the
2240
- adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
2241
- urls with the "jdbc" prefix were passed to the Active Record Adapter, others
2242
- are assumed to be adapter specification urls.
1036
+ You can also call `full_inspect` to get an inspection with all the attributes.
2243
1037
 
2244
- Fixes #41137.
1038
+ The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
2245
1039
 
2246
- *Jonathan Bracy*
2247
-
2248
- * Allow to opt-out of `strict_loading` mode on a per-record base.
2249
-
2250
- This is useful when strict loading is enabled application wide or on a
2251
- model level.
2252
-
2253
- ```ruby
2254
- class User < ApplicationRecord
2255
- has_many :bookmarks
2256
- has_many :articles, strict_loading: true
2257
- end
1040
+ *Andrew Novoselac*
2258
1041
 
2259
- user = User.first
2260
- user.articles # => ActiveRecord::StrictLoadingViolationError
2261
- user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
1042
+ * Don't mark attributes as changed when reassigned to `Float::INFINITY` or
1043
+ `-Float::INFINITY`.
2262
1044
 
2263
- user.strict_loading!(true) # => true
2264
- user.bookmarks # => ActiveRecord::StrictLoadingViolationError
1045
+ *Maicol Bentancor*
2265
1046
 
2266
- user.strict_loading!(false) # => false
2267
- user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
2268
- user.articles.strict_loading!(false) # => #<ActiveRecord::Associations::CollectionProxy>
2269
- ```
1047
+ * Support the `RETURNING` clause for MariaDB.
2270
1048
 
2271
- *Ayrton De Craene*
1049
+ *fatkodima*, *Nikolay Kondratyev*
2272
1050
 
2273
- * Add `FinderMethods#sole` and `#find_sole_by` to find and assert the
2274
- presence of exactly one record.
1051
+ * The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
2275
1052
 
2276
- Used when you need a single row, but also want to assert that there aren't
2277
- multiple rows matching the condition; especially for when database
2278
- constraints aren't enough or are impractical.
1053
+ Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
2279
1054
 
2280
1055
  ```ruby
2281
- Product.where(["price = %?", price]).sole
2282
- # => ActiveRecord::RecordNotFound (if no Product with given price)
2283
- # => #<Product ...> (if one Product with given price)
2284
- # => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
2285
-
2286
- user.api_keys.find_sole_by(key: key)
2287
- # as above
1056
+ add_reference :person, :alias, foreign_key: { deferrable: :deferred }
1057
+ add_reference :alias, :person, foreign_key: { deferrable: :deferred }
2288
1058
  ```
2289
1059
 
2290
- *Asherah Connor*
1060
+ *Stephen Margheim*
2291
1061
 
2292
- * Makes `ActiveRecord::AttributeMethods::Query` respect the getter overrides defined in the model.
2293
-
2294
- Before:
1062
+ * Add the `set_constraints` helper to PostgreSQL connections.
2295
1063
 
2296
1064
  ```ruby
2297
- class User
2298
- def admin
2299
- false # Overriding the getter to always return false
2300
- end
2301
- end
2302
-
2303
- user = User.first
2304
- user.update(admin: true)
2305
-
2306
- user.admin # false (as expected, due to the getter overwrite)
2307
- user.admin? # true (not expected, returned the DB column value)
2308
- ```
2309
-
2310
- After this commit, `user.admin?` above returns false, as expected.
1065
+ Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
2311
1066
 
2312
- Fixes #40771.
2313
-
2314
- *Felipe*
2315
-
2316
- * Allow delegated_type to be specified primary_key and foreign_key.
2317
-
2318
- Since delegated_type assumes that the foreign_key ends with `_id`,
2319
- `singular_id` defined by it does not work when the foreign_key does
2320
- not end with `id`. This change fixes it by taking into account
2321
- `primary_key` and `foreign_key` in the options.
2322
-
2323
- *Ryota Egusa*
2324
-
2325
- * Expose an `invert_where` method that will invert all scope conditions.
2326
-
2327
- ```ruby
2328
- class User
2329
- scope :active, -> { where(accepted: true, locked: false) }
1067
+ Post.transaction do
1068
+ Post.connection.set_constraints(:deferred)
1069
+ p = Post.create!(user_id: -1)
1070
+ u = User.create!
1071
+ p.user = u
1072
+ p.save!
2330
1073
  end
2331
-
2332
- User.active
2333
- # ... WHERE `accepted` = 1 AND `locked` = 0
2334
-
2335
- User.active.invert_where
2336
- # ... WHERE NOT (`accepted` = 1 AND `locked` = 0)
2337
- ```
2338
-
2339
- *Kevin Deisz*
2340
-
2341
- * Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
2342
-
2343
- Previously, passing `false` would trigger the option validation logic
2344
- to throw an error saying :polymorphic would not be a valid option.
2345
-
2346
- *glaszig*
2347
-
2348
- * Remove deprecated `database` kwarg from `connected_to`.
2349
-
2350
- *Eileen M. Uchitelle*, *John Crepezzi*
2351
-
2352
- * Allow adding nonnamed expression indexes to be revertible.
2353
-
2354
- Previously, the following code would raise an error, when executed while rolling back,
2355
- and the index name should be specified explicitly. Now, the index name is inferred
2356
- automatically.
2357
-
2358
- ```ruby
2359
- add_index(:items, "to_tsvector('english', description)")
2360
1074
  ```
2361
1075
 
2362
- Fixes #40732.
2363
-
2364
- *fatkodima*
2365
-
2366
- * Only warn about negative enums if a positive form that would cause conflicts exists.
2367
-
2368
- Fixes #39065.
1076
+ *Cody Cutrer*
2369
1077
 
2370
- *Alex Ghiculescu*
1078
+ * Include `ActiveModel::API` in `ActiveRecord::Base`.
2371
1079
 
2372
- * Add option to run `default_scope` on all queries.
1080
+ *Sean Doyle*
2373
1081
 
2374
- Previously, a `default_scope` would only run on select or insert queries. In some cases, like non-Rails tenant sharding solutions, it may be desirable to run `default_scope` on all queries in order to ensure queries are including a foreign key for the shard (i.e. `blog_id`).
1082
+ * Ensure `#signed_id` outputs `url_safe` strings.
2375
1083
 
2376
- Now applications can add an option to run on all queries including select, insert, delete, and update by adding an `all_queries` option to the default scope definition.
1084
+ *Jason Meller*
2377
1085
 
2378
- ```ruby
2379
- class Article < ApplicationRecord
2380
- default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
2381
- end
2382
- ```
1086
+ * Add `nulls_last` and working `desc.nulls_first` for MySQL.
2383
1087
 
2384
- *Eileen M. Uchitelle*
1088
+ *Tristan Fellows*
2385
1089
 
2386
- * Add `where.associated` to check for the presence of an association.
1090
+ * Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
2387
1091
 
2388
1092
  ```ruby
2389
- # Before:
2390
- account.users.joins(:contact).where.not(contact_id: nil)
2391
-
2392
- # After:
2393
- account.users.where.associated(:contact)
1093
+ Topic.includes(:posts).order(posts: { created_at: :desc })
2394
1094
  ```
2395
1095
 
2396
- Also mirrors `where.missing`.
2397
-
2398
- *Kasper Timm Hansen*
2399
-
2400
- * Allow constructors (`build_association` and `create_association`) on
2401
- `has_one :through` associations.
2402
-
2403
- *Santiago Perez Perret*
2404
-
1096
+ *Myles Boone*
2405
1097
 
2406
- Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activerecord/CHANGELOG.md) for previous changes.
1098
+ Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activerecord/CHANGELOG.md) for previous changes.