activerecord 7.0.8.7 → 7.2.3

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