activerecord 6.0.0 → 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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +996 -594
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +34 -34
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +22 -20
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +41 -30
  9. data/lib/active_record/associations/association.rb +106 -41
  10. data/lib/active_record/associations/association_scope.rb +30 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +69 -14
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
  13. data/lib/active_record/associations/builder/association.rb +39 -6
  14. data/lib/active_record/associations/builder/belongs_to.rb +47 -17
  15. data/lib/active_record/associations/builder/collection_association.rb +14 -6
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
  17. data/lib/active_record/associations/builder/has_many.rb +7 -3
  18. data/lib/active_record/associations/builder/has_one.rb +13 -16
  19. data/lib/active_record/associations/builder/singular_association.rb +7 -3
  20. data/lib/active_record/associations/collection_association.rb +90 -53
  21. data/lib/active_record/associations/collection_proxy.rb +54 -19
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/errors.rb +265 -0
  24. data/lib/active_record/associations/foreign_association.rb +21 -1
  25. data/lib/active_record/associations/has_many_association.rb +41 -10
  26. data/lib/active_record/associations/has_many_through_association.rb +29 -12
  27. data/lib/active_record/associations/has_one_association.rb +33 -9
  28. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  29. data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
  30. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  31. data/lib/active_record/associations/join_dependency.rb +97 -54
  32. data/lib/active_record/associations/nested_error.rb +47 -0
  33. data/lib/active_record/associations/preloader/association.rb +237 -54
  34. data/lib/active_record/associations/preloader/batch.rb +48 -0
  35. data/lib/active_record/associations/preloader/branch.rb +153 -0
  36. data/lib/active_record/associations/preloader/through_association.rb +51 -17
  37. data/lib/active_record/associations/preloader.rb +55 -121
  38. data/lib/active_record/associations/singular_association.rb +16 -4
  39. data/lib/active_record/associations/through_association.rb +26 -15
  40. data/lib/active_record/associations.rb +454 -440
  41. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  42. data/lib/active_record/attribute_assignment.rb +11 -14
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
  44. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  45. data/lib/active_record/attribute_methods/dirty.rb +75 -34
  46. data/lib/active_record/attribute_methods/primary_key.rb +53 -31
  47. data/lib/active_record/attribute_methods/query.rb +31 -22
  48. data/lib/active_record/attribute_methods/read.rb +16 -17
  49. data/lib/active_record/attribute_methods/serialization.rb +177 -35
  50. data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
  51. data/lib/active_record/attribute_methods/write.rb +16 -28
  52. data/lib/active_record/attribute_methods.rb +227 -100
  53. data/lib/active_record/attributes.rb +94 -56
  54. data/lib/active_record/autosave_association.rb +119 -73
  55. data/lib/active_record/base.rb +31 -21
  56. data/lib/active_record/callbacks.rb +168 -55
  57. data/lib/active_record/coders/column_serializer.rb +61 -0
  58. data/lib/active_record/coders/json.rb +1 -1
  59. data/lib/active_record/coders/yaml_column.rb +70 -25
  60. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
  64. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
  65. data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
  66. data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
  67. data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
  68. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  69. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  70. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
  71. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
  72. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
  73. data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
  74. data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
  75. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
  76. data/lib/active_record/connection_adapters/column.rb +28 -1
  77. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  78. data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
  79. data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
  80. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  81. data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
  82. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
  83. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
  84. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
  85. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
  86. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  87. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  88. data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
  89. data/lib/active_record/connection_adapters/pool_config.rb +83 -0
  90. data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
  91. data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
  92. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
  93. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -5
  95. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  97. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -15
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  101. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
  103. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  105. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
  106. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  110. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
  111. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
  121. data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  123. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  124. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
  131. data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
  132. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  133. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  134. data/lib/active_record/connection_adapters.rb +176 -0
  135. data/lib/active_record/connection_handling.rb +243 -115
  136. data/lib/active_record/core.rb +481 -199
  137. data/lib/active_record/counter_cache.rb +69 -32
  138. data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
  139. data/lib/active_record/database_configurations/database_config.rb +77 -10
  140. data/lib/active_record/database_configurations/hash_config.rb +148 -26
  141. data/lib/active_record/database_configurations/url_config.rb +44 -45
  142. data/lib/active_record/database_configurations.rb +190 -114
  143. data/lib/active_record/delegated_type.rb +279 -0
  144. data/lib/active_record/deprecator.rb +7 -0
  145. data/lib/active_record/destroy_association_async_job.rb +38 -0
  146. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  147. data/lib/active_record/dynamic_matchers.rb +5 -6
  148. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  149. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  150. data/lib/active_record/encryption/cipher.rb +53 -0
  151. data/lib/active_record/encryption/config.rb +68 -0
  152. data/lib/active_record/encryption/configurable.rb +60 -0
  153. data/lib/active_record/encryption/context.rb +42 -0
  154. data/lib/active_record/encryption/contexts.rb +76 -0
  155. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  156. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  157. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  158. data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
  159. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  160. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  161. data/lib/active_record/encryption/encryptor.rb +171 -0
  162. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  163. data/lib/active_record/encryption/errors.rb +15 -0
  164. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  165. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  166. data/lib/active_record/encryption/key.rb +28 -0
  167. data/lib/active_record/encryption/key_generator.rb +53 -0
  168. data/lib/active_record/encryption/key_provider.rb +46 -0
  169. data/lib/active_record/encryption/message.rb +33 -0
  170. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  171. data/lib/active_record/encryption/message_serializer.rb +96 -0
  172. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  173. data/lib/active_record/encryption/properties.rb +76 -0
  174. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  175. data/lib/active_record/encryption/scheme.rb +100 -0
  176. data/lib/active_record/encryption.rb +58 -0
  177. data/lib/active_record/enum.rb +224 -73
  178. data/lib/active_record/errors.rb +254 -36
  179. data/lib/active_record/explain.rb +30 -17
  180. data/lib/active_record/explain_registry.rb +11 -6
  181. data/lib/active_record/explain_subscriber.rb +2 -2
  182. data/lib/active_record/fixture_set/file.rb +22 -15
  183. data/lib/active_record/fixture_set/model_metadata.rb +15 -6
  184. data/lib/active_record/fixture_set/render_context.rb +3 -1
  185. data/lib/active_record/fixture_set/table_row.rb +88 -16
  186. data/lib/active_record/fixture_set/table_rows.rb +4 -5
  187. data/lib/active_record/fixtures.rb +229 -116
  188. data/lib/active_record/future_result.rb +178 -0
  189. data/lib/active_record/gem_version.rb +4 -4
  190. data/lib/active_record/inheritance.rb +121 -48
  191. data/lib/active_record/insert_all.rb +178 -29
  192. data/lib/active_record/integration.rb +16 -14
  193. data/lib/active_record/internal_metadata.rb +132 -21
  194. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  195. data/lib/active_record/locking/optimistic.rb +64 -33
  196. data/lib/active_record/locking/pessimistic.rb +21 -8
  197. data/lib/active_record/log_subscriber.rb +61 -30
  198. data/lib/active_record/marshalling.rb +59 -0
  199. data/lib/active_record/message_pack.rb +124 -0
  200. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  201. data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
  202. data/lib/active_record/middleware/database_selector.rb +25 -13
  203. data/lib/active_record/middleware/shard_selector.rb +62 -0
  204. data/lib/active_record/migration/command_recorder.rb +160 -55
  205. data/lib/active_record/migration/compatibility.rb +286 -43
  206. data/lib/active_record/migration/default_strategy.rb +22 -0
  207. data/lib/active_record/migration/execution_strategy.rb +19 -0
  208. data/lib/active_record/migration/join_table.rb +1 -2
  209. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  210. data/lib/active_record/migration.rb +421 -193
  211. data/lib/active_record/model_schema.rb +217 -125
  212. data/lib/active_record/nested_attributes.rb +62 -27
  213. data/lib/active_record/no_touching.rb +4 -4
  214. data/lib/active_record/normalization.rb +163 -0
  215. data/lib/active_record/persistence.rb +322 -319
  216. data/lib/active_record/promise.rb +84 -0
  217. data/lib/active_record/query_cache.rb +18 -15
  218. data/lib/active_record/query_logs.rb +193 -0
  219. data/lib/active_record/query_logs_formatter.rb +41 -0
  220. data/lib/active_record/querying.rb +54 -14
  221. data/lib/active_record/railtie.rb +250 -72
  222. data/lib/active_record/railties/console_sandbox.rb +2 -4
  223. data/lib/active_record/railties/controller_runtime.rb +25 -11
  224. data/lib/active_record/railties/databases.rake +312 -197
  225. data/lib/active_record/railties/job_runtime.rb +23 -0
  226. data/lib/active_record/readonly_attributes.rb +45 -3
  227. data/lib/active_record/reflection.rb +389 -146
  228. data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
  229. data/lib/active_record/relation/batches.rb +214 -73
  230. data/lib/active_record/relation/calculations.rb +379 -124
  231. data/lib/active_record/relation/delegation.rb +36 -23
  232. data/lib/active_record/relation/finder_methods.rb +159 -49
  233. data/lib/active_record/relation/from_clause.rb +5 -1
  234. data/lib/active_record/relation/merger.rb +41 -33
  235. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
  236. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
  237. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
  238. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  239. data/lib/active_record/relation/predicate_builder.rb +79 -53
  240. data/lib/active_record/relation/query_attribute.rb +30 -12
  241. data/lib/active_record/relation/query_methods.rb +1156 -279
  242. data/lib/active_record/relation/record_fetch_warning.rb +12 -11
  243. data/lib/active_record/relation/spawn_methods.rb +10 -9
  244. data/lib/active_record/relation/where_clause.rb +100 -66
  245. data/lib/active_record/relation.rb +829 -194
  246. data/lib/active_record/result.rb +76 -56
  247. data/lib/active_record/runtime_registry.rb +71 -13
  248. data/lib/active_record/sanitization.rb +86 -47
  249. data/lib/active_record/schema.rb +39 -23
  250. data/lib/active_record/schema_dumper.rb +140 -33
  251. data/lib/active_record/schema_migration.rb +74 -29
  252. data/lib/active_record/scoping/default.rb +73 -19
  253. data/lib/active_record/scoping/named.rb +10 -28
  254. data/lib/active_record/scoping.rb +65 -35
  255. data/lib/active_record/secure_password.rb +60 -0
  256. data/lib/active_record/secure_token.rb +34 -8
  257. data/lib/active_record/serialization.rb +11 -4
  258. data/lib/active_record/signed_id.rb +138 -0
  259. data/lib/active_record/statement_cache.rb +26 -10
  260. data/lib/active_record/store.rb +19 -14
  261. data/lib/active_record/suppressor.rb +15 -17
  262. data/lib/active_record/table_metadata.rb +46 -36
  263. data/lib/active_record/tasks/database_tasks.rb +371 -205
  264. data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
  265. data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
  266. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
  267. data/lib/active_record/test_databases.rb +5 -4
  268. data/lib/active_record/test_fixtures.rb +189 -104
  269. data/lib/active_record/testing/query_assertions.rb +121 -0
  270. data/lib/active_record/timestamp.rb +35 -25
  271. data/lib/active_record/token_for.rb +123 -0
  272. data/lib/active_record/touch_later.rb +31 -27
  273. data/lib/active_record/transaction.rb +132 -0
  274. data/lib/active_record/transactions.rb +131 -99
  275. data/lib/active_record/translation.rb +3 -5
  276. data/lib/active_record/type/adapter_specific_registry.rb +33 -18
  277. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  278. data/lib/active_record/type/internal/timezone.rb +7 -2
  279. data/lib/active_record/type/serialized.rb +11 -6
  280. data/lib/active_record/type/time.rb +14 -0
  281. data/lib/active_record/type/type_map.rb +17 -21
  282. data/lib/active_record/type/unsigned_integer.rb +0 -1
  283. data/lib/active_record/type.rb +7 -2
  284. data/lib/active_record/type_caster/connection.rb +4 -5
  285. data/lib/active_record/type_caster/map.rb +8 -5
  286. data/lib/active_record/validations/absence.rb +1 -1
  287. data/lib/active_record/validations/associated.rb +13 -8
  288. data/lib/active_record/validations/numericality.rb +36 -0
  289. data/lib/active_record/validations/presence.rb +5 -28
  290. data/lib/active_record/validations/uniqueness.rb +88 -18
  291. data/lib/active_record/validations.rb +15 -8
  292. data/lib/active_record/version.rb +1 -1
  293. data/lib/active_record.rb +446 -40
  294. data/lib/arel/alias_predication.rb +1 -1
  295. data/lib/arel/attributes/attribute.rb +4 -8
  296. data/lib/arel/collectors/bind.rb +8 -1
  297. data/lib/arel/collectors/composite.rb +15 -0
  298. data/lib/arel/collectors/sql_string.rb +7 -0
  299. data/lib/arel/collectors/substitute_binds.rb +7 -0
  300. data/lib/arel/crud.rb +30 -22
  301. data/lib/arel/delete_manager.rb +23 -4
  302. data/lib/arel/errors.rb +10 -0
  303. data/lib/arel/factory_methods.rb +4 -0
  304. data/lib/arel/filter_predications.rb +9 -0
  305. data/lib/arel/insert_manager.rb +2 -3
  306. data/lib/arel/nodes/binary.rb +82 -9
  307. data/lib/arel/nodes/bind_param.rb +8 -0
  308. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  309. data/lib/arel/nodes/casted.rb +22 -10
  310. data/lib/arel/nodes/cte.rb +36 -0
  311. data/lib/arel/nodes/delete_statement.rb +14 -13
  312. data/lib/arel/nodes/equality.rb +6 -9
  313. data/lib/arel/nodes/filter.rb +10 -0
  314. data/lib/arel/nodes/fragments.rb +35 -0
  315. data/lib/arel/nodes/function.rb +1 -0
  316. data/lib/arel/nodes/grouping.rb +3 -0
  317. data/lib/arel/nodes/homogeneous_in.rb +68 -0
  318. data/lib/arel/nodes/in.rb +8 -1
  319. data/lib/arel/nodes/infix_operation.rb +13 -1
  320. data/lib/arel/nodes/insert_statement.rb +2 -2
  321. data/lib/arel/nodes/join_source.rb +1 -1
  322. data/lib/arel/nodes/leading_join.rb +8 -0
  323. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  324. data/lib/arel/nodes/node.rb +122 -11
  325. data/lib/arel/nodes/ordering.rb +27 -0
  326. data/lib/arel/nodes/select_core.rb +2 -2
  327. data/lib/arel/nodes/select_statement.rb +2 -2
  328. data/lib/arel/nodes/sql_literal.rb +16 -0
  329. data/lib/arel/nodes/table_alias.rb +11 -3
  330. data/lib/arel/nodes/unary.rb +0 -1
  331. data/lib/arel/nodes/update_statement.rb +11 -4
  332. data/lib/arel/nodes.rb +10 -3
  333. data/lib/arel/predications.rb +31 -28
  334. data/lib/arel/select_manager.rb +18 -9
  335. data/lib/arel/table.rb +21 -10
  336. data/lib/arel/tree_manager.rb +8 -15
  337. data/lib/arel/update_manager.rb +25 -5
  338. data/lib/arel/visitors/dot.rb +94 -90
  339. data/lib/arel/visitors/mysql.rb +34 -6
  340. data/lib/arel/visitors/postgresql.rb +5 -16
  341. data/lib/arel/visitors/sqlite.rb +25 -1
  342. data/lib/arel/visitors/to_sql.rb +227 -81
  343. data/lib/arel/visitors/visitor.rb +2 -3
  344. data/lib/arel/visitors.rb +0 -7
  345. data/lib/arel.rb +37 -15
  346. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  347. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  348. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  349. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  350. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
  351. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  352. data/lib/rails/generators/active_record/migration.rb +9 -3
  353. data/lib/rails/generators/active_record/model/USAGE +113 -0
  354. data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
  355. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  356. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  357. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  358. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  359. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  360. metadata +117 -30
  361. data/lib/active_record/attribute_decorators.rb +0 -90
  362. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  363. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  364. data/lib/active_record/define_callbacks.rb +0 -22
  365. data/lib/active_record/null_relation.rb +0 -68
  366. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  367. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  368. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  369. data/lib/arel/attributes.rb +0 -22
  370. data/lib/arel/visitors/depth_first.rb +0 -204
  371. data/lib/arel/visitors/ibm_db.rb +0 -34
  372. data/lib/arel/visitors/informix.rb +0 -62
  373. data/lib/arel/visitors/mssql.rb +0 -157
  374. data/lib/arel/visitors/oracle.rb +0 -159
  375. data/lib/arel/visitors/oracle12.rb +0 -66
  376. data/lib/arel/visitors/where_sql.rb +0 -23
data/CHANGELOG.md CHANGED
@@ -1,1013 +1,1415 @@
1
- ## Rails 6.0.0 (August 16, 2019) ##
1
+ ## Rails 7.2.3 (October 28, 2025) ##
2
2
 
3
- * Preserve user supplied joins order as much as possible.
3
+ * Fix SQLite3 data loss during table alterations with CASCADE foreign keys.
4
4
 
5
- Fixes #36761, #34328, #24281, #12953.
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.
6
10
 
7
- *Ryuta Kamizono*
8
-
9
- * Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.
10
-
11
- *John Crepezzi*, *Eileen Uchitelle*
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.
12
16
 
13
- * Add a warning for enum elements with 'not_' prefix.
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.
14
22
 
15
- class Foo
16
- enum status: [:sent, :not_sent]
17
- end
18
-
19
- *Edu Depetris*
23
+ *Ruy Rocha*
20
24
 
21
- * Make currency symbols optional for money column type in PostgreSQL
25
+ * Fix `belongs_to` associations not to clear the entire composite primary key.
22
26
 
23
- *Joel Schneider*
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.
24
29
 
30
+ *zzak*
25
31
 
26
- ## Rails 6.0.0.rc2 (July 22, 2019) ##
32
+ * Fix invalid records being autosaved when distantly associated records are marked for deletion.
27
33
 
28
- * Add database_exists? method to connection adapters to check if a database exists.
34
+ *Ian Terrell*, *axlekb AB*
29
35
 
30
- *Guilherme Mansur*
36
+ * Prevent persisting invalid record.
31
37
 
32
- * PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
38
+ *Edouard Chin*
33
39
 
34
- Fixes #36022.
40
+ * Fix count with group by qualified name on loaded relation.
35
41
 
36
42
  *Ryuta Kamizono*
37
43
 
38
- * Make ActiveRecord `ConnectionPool.connections` method thread-safe.
44
+ * Fix `sum` with qualified name on loaded relation.
39
45
 
40
- Fixes #36465.
46
+ *Chris Gunther*
41
47
 
42
- *Jeff Doering*
48
+ * Fix prepared statements on mysql2 adapter.
43
49
 
44
- * Fix sqlite3 collation parsing when using decimal columns.
50
+ *Jean Boussier*
45
51
 
46
- *Martin R. Schuster*
52
+ * Fix query cache for pinned connections in multi threaded transactional tests.
47
53
 
48
- * Fix invalid schema when primary key column has a comment.
54
+ When a pinned connection is used across separate threads, they now use a separate cache store
55
+ for each thread.
49
56
 
50
- Fixes #29966.
57
+ This improve accuracy of system tests, and any test using multiple threads.
51
58
 
52
- *Guilherme Goettems Schneider*
59
+ *Heinrich Lee Yu*, *Jean Boussier*
53
60
 
54
- * Fix table comment also being applied to the primary key column.
61
+ * Don't add `id_value` attribute alias when attribute/column with that name already exists.
55
62
 
56
- *Guilherme Goettems Schneider*
63
+ *Rob Lewis*
57
64
 
58
- * Fix merging left_joins to maintain its own `join_type` context.
65
+ * Fix false positive change detection involving STI and polymorhic has one relationships.
59
66
 
60
- Fixes #36103.
67
+ Polymorphic `has_one` relationships would always be considered changed when defined in a STI child
68
+ class, causing nedless extra autosaves.
61
69
 
62
- *Ryuta Kamizono*
70
+ *David Fritsch*
63
71
 
72
+ * Fix stale associaton detection for polymophic `belong_to`.
64
73
 
65
- ## Rails 6.0.0.rc1 (April 24, 2019) ##
74
+ *Florent Beaurain*, *Thomas Crambert*
66
75
 
67
- * Add `touch` option to `has_one` association.
76
+ * Fix removal of PostgreSQL version comments in `structure.sql` for latest PostgreSQL versions which include `\restrict`.
68
77
 
69
- *Abhay Nikam*
78
+ *Brendan Weibrecht*
70
79
 
71
- * Deprecate `where.not` working as NOR and will be changed to NAND in Rails 6.1.
80
+ * Fix `#merge` with `#or` or `#and` and a mixture of attributes and SQL strings resulting in an incorrect query.
72
81
 
73
82
  ```ruby
74
- all = [treasures(:diamond), treasures(:sapphire), cars(:honda), treasures(:sapphire)]
75
- assert_equal all, PriceEstimate.all.map(&:estimate_of)
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
76
85
  ```
77
86
 
78
- In Rails 6.0:
87
+ Before:
79
88
 
80
- ```ruby
81
- sapphire = treasures(:sapphire)
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
+ )
99
+ ```
82
100
 
83
- nor = all.reject { |e|
84
- e.estimate_of_type == sapphire.class.polymorphic_name
85
- }.reject { |e|
86
- e.estimate_of_id == sapphire.id
87
- }
88
- assert_equal [cars(:honda)], nor
101
+ After:
89
102
 
90
- without_sapphire = PriceEstimate.where.not(
91
- estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
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
92
113
  )
93
- assert_equal nor, without_sapphire.map(&:estimate_of)
94
114
  ```
95
115
 
96
- In Rails 6.1:
116
+ *Joshua Young*
97
117
 
98
- ```ruby
99
- sapphire = treasures(:sapphire)
118
+ * Fix inline `has_and_belongs_to_many` fixtures for tables with composite primary keys.
100
119
 
101
- nand = all - [sapphire]
102
- assert_equal [treasures(:diamond), cars(:honda)], nand
120
+ *fatkodima*
103
121
 
104
- without_sapphire = PriceEstimate.where.not(
105
- estimate_of_type: sapphire.class.polymorphic_name, estimate_of_id: sapphire.id
106
- )
107
- assert_equal nand, without_sapphire.map(&:estimate_of)
108
- ```
122
+ * Fix `annotate` comments to propagate to `update_all`/`delete_all`.
109
123
 
110
- *Ryuta Kamizono*
124
+ *fatkodima*
111
125
 
112
- * Fix dirty tracking after rollback.
126
+ * Fix checking whether an unpersisted record is `include?`d in a strictly
127
+ loaded `has_and_belongs_to_many` association.
113
128
 
114
- Fixes #15018, #30167, #33868.
129
+ *Hartley McGuire*
115
130
 
116
- *Ryuta Kamizono*
131
+ * Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys.
117
132
 
118
- * Add `ActiveRecord::Relation#cache_version` to support recyclable cache keys via
119
- the versioned entries in `ActiveSupport::Cache`. This also means that
120
- `ActiveRecord::Relation#cache_key` will now return a stable key that does not
121
- include the max timestamp or count any more.
133
+ *fatkodima*
122
134
 
123
- NOTE: This feature is turned off by default, and `cache_key` will still return
124
- cache keys with timestamps until you set `ActiveRecord::Base.collection_cache_versioning = true`.
125
- That's the setting for all new apps on Rails 6.0+
135
+ * `create_or_find_by` will now correctly rollback a transaction.
126
136
 
127
- *Lachlan Sylvester*
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.
128
140
 
129
- * Fix dirty tracking for `touch` to track saved changes.
141
+ *Edouard Chin*
130
142
 
131
- Fixes #33429.
143
+ * Gracefully handle `Timeout.timeout` firing during connection configuration.
132
144
 
133
- *Ryuta Kamzono*
145
+ Use of `Timeout.timeout` could result in improperly initialized database connection.
134
146
 
135
- * `change_column_comment` and `change_table_comment` are invertible only if
136
- `to` and `from` options are specified.
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)`.
137
150
 
138
- *Yoshiyuki Kinjo*
151
+ *Jean Boussier*
139
152
 
140
- * Don't call commit/rollback callbacks when a record isn't saved.
153
+ * The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".
141
154
 
142
- Fixes #29747.
155
+ *Mike Dalessio*
143
156
 
144
- *Ryuta Kamizono*
157
+ * Handle libpq returning a database version of 0 on no/bad connection in `PostgreSQLAdapter`.
145
158
 
146
- * Fix circular `autosave: true` causes invalid records to be saved.
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
- Prior to the fix, when there was a circular series of `autosave: true`
149
- associations, the callback for a `has_many` association was run while
150
- another instance of the same callback on the same association hadn't
151
- finished running. When control returned to the first instance of the
152
- callback, the instance variable had changed, and subsequent associated
153
- records weren't saved correctly. Specifically, the ID field for the
154
- `belongs_to` corresponding to the `has_many` was `nil`.
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.
155
165
 
156
- Fixes #28080.
166
+ *Joshua Young*, *Rian McGuire*
157
167
 
158
- *Larry Reid*
168
+ * Fix error handling during connection configuration.
159
169
 
160
- * Raise `ArgumentError` for invalid `:limit` and `:precision` like as other options.
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)`.
161
174
 
162
- Before:
175
+ *Jean Boussier*
176
+
177
+ * Fix a case where a non-retryable query could be marked retryable.
178
+
179
+ *Hartley McGuire*
180
+
181
+ * Handle circular references when autosaving associations.
182
+
183
+ *zzak*
184
+
185
+ * Prevent persisting invalid record.
186
+
187
+ *Edouard Chin*
188
+
189
+ * Fix support for PostgreSQL enum types with commas in their name.
190
+
191
+ *Arthur Hess*
192
+
193
+ * Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.
194
+
195
+ *Nikita Vasilevsky*
196
+
197
+ * Fix joining on a scoped association with string joins and bind parameters.
163
198
 
164
199
  ```ruby
165
- add_column :items, :attr1, :binary, size: 10 # => ArgumentError
166
- add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
167
- add_column :items, :attr3, :integer, limit: 10 # => ActiveRecordError
168
- add_column :items, :attr4, :datetime, precision: 10 # => ActiveRecordError
200
+ class Instructor < ActiveRecord::Base
201
+ has_many :instructor_roles, -> { active }
202
+ end
203
+
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
210
+
211
+ Instructor.joins(:instructor_roles).first
169
212
  ```
170
213
 
171
- After:
214
+ The above example would result in `ActiveRecord::StatementInvalid` because the
215
+ `active` scope bind parameters would be lost.
216
+
217
+ *Jean Boussier*
218
+
219
+ * Fix a potential race condition with system tests and transactional fixtures.
220
+
221
+ *Sjoerd Lagarde*
222
+
223
+ * Fix count with group by qualified name on loaded relation.
224
+
225
+ *Ryuta Kamizono*
226
+
227
+ * Fix sum with qualified name on loaded relation.
228
+
229
+ *Chris Gunther*
230
+
231
+ * Fix autosave associations to no longer validated unmodified associated records.
232
+
233
+ Active Record was incorrectly performing validation on associated record that
234
+ weren't created nor modified as part of the transaction:
172
235
 
173
236
  ```ruby
174
- add_column :items, :attr1, :binary, size: 10 # => ArgumentError
175
- add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
176
- add_column :items, :attr3, :integer, limit: 10 # => ArgumentError
177
- add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
237
+ Post.create!(author: User.find(1)) # Fail if user is invalid
178
238
  ```
179
239
 
240
+ *Jean Boussier*
241
+
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.
245
+
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.
249
+
250
+ *Matthew Draper*
251
+
252
+ * Fix prepared statements on mysql2 adapter.
253
+
254
+ *Jean Boussier*
255
+
256
+ * Fix a race condition in `ActiveRecord::Base#method_missing` when lazily defining attributes.
257
+
258
+ If multiple thread were concurrently triggering attribute definition on the same model,
259
+ it could result in a `NoMethodError` being raised.
260
+
261
+ *Jean Boussier*
262
+
263
+ * Fix MySQL default functions getting dropped when changing a column's nullability.
264
+
265
+ *Bastian Bartmann*
266
+
267
+ * Fix `add_unique_constraint`/`add_check_constraint`/`/`add_foreign_key` to be revertible when
268
+ given invalid options.
269
+
270
+ *fatkodima*
271
+
272
+ * Fix asynchronous destroying of polymorphic `belongs_to` associations.
273
+
274
+ *fatkodima*
275
+
276
+ * NOT VALID constraints should not dump in `create_table`.
277
+
180
278
  *Ryuta Kamizono*
181
279
 
182
- * Association loading isn't to be affected by scoping consistently
183
- whether preloaded / eager loaded or not, with the exception of `unscoped`.
280
+ * Fix finding by nil composite primary key association.
184
281
 
185
- Before:
282
+ *fatkodima*
283
+
284
+ * Fix parsing of SQLite foreign key names when they contain non-ASCII characters
285
+
286
+ *Zacharias Knudsen*
287
+
288
+ * Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines.
289
+
290
+ *Steve Hill*
291
+
292
+ * Ensure normalized attribute queries use `IS NULL` consistently for `nil` and normalized `nil` values.
293
+
294
+ *Joshua Young*
295
+
296
+ * Restore back the ability to pass only database name for `DATABASE_URL`.
297
+
298
+ *fatkodima*
299
+
300
+ * Fix `order` with using association name as an alias.
301
+
302
+ *Ryuta Kamizono*
303
+
304
+ * Improve invalid argument error for with.
305
+
306
+ *Ryuta Kamizono*
307
+
308
+ * Deduplicate `with` CTE expressions.
309
+
310
+ *fatkodima*
311
+
312
+
313
+ ## Rails 7.2.2.2 (August 13, 2025) ##
314
+
315
+ * Call inspect on ids in RecordNotFound error
316
+
317
+ [CVE-2025-55193]
318
+
319
+ *Gannon McGibbon*, *John Hawthorn*
320
+
321
+
322
+ ## Rails 7.2.2.1 (December 10, 2024) ##
323
+
324
+ * No changes.
325
+
326
+
327
+ ## Rails 7.2.2 (October 30, 2024) ##
328
+
329
+ * Fix support for `query_cache: false` in `database.yml`.
330
+
331
+ `query_cache: false` would no longer entirely disable the Active Record query cache.
332
+
333
+ *zzak*
334
+
335
+ * Set `.attributes_for_inspect` to `:all` by default.
336
+
337
+ For new applications it is set to `[:id]` in config/environment/production.rb.
338
+
339
+ In the console all the attributes are always shown.
340
+
341
+ *Andrew Novoselac*
342
+
343
+ * `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
344
+
345
+ *Kazuma Watanabe*
346
+
347
+ * Fix marshalling of unsaved associated records in 7.1 format.
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.
351
+
352
+ *Jean Boussier*
353
+
354
+ * Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
355
+
356
+ *David Stosik*
357
+
358
+ * Allow to save records with polymorphic join tables that have `inverse_of`
359
+ specified.
360
+
361
+ *Markus Doits*
362
+
363
+ * Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
364
+
365
+ *Joshua Young*
366
+
367
+ * Fix `dependent: :destroy` for bi-directional has one through association.
368
+
369
+ Fixes #50948.
186
370
 
187
371
  ```ruby
188
- Post.where("1=0").scoping do
189
- Comment.find(1).post # => nil
190
- Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
191
- Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
372
+ class Left < ActiveRecord::Base
373
+ has_one :middle, dependent: :destroy
374
+ has_one :right, through: :middle
375
+ end
376
+
377
+ class Middle < ActiveRecord::Base
378
+ belongs_to :left, dependent: :destroy
379
+ belongs_to :right, dependent: :destroy
380
+ end
381
+
382
+ class Right < ActiveRecord::Base
383
+ has_one :middle, dependent: :destroy
384
+ has_one :left, through: :middle
192
385
  end
193
386
  ```
387
+ In the above example `left.destroy` wouldn't destroy its associated `Right`
388
+ record.
194
389
 
195
- After:
390
+ *Andy Stewart*
391
+
392
+ * Properly handle lazily pinned connection pools.
393
+
394
+ Fixes #53147.
395
+
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.
400
+
401
+ *Jean Boussier*
402
+
403
+ * Fix `ActiveRecord::Base.with` to accept more than two sub queries.
404
+
405
+ Fixes #53110.
196
406
 
197
407
  ```ruby
198
- Post.where("1=0").scoping do
199
- Comment.find(1).post # => #<Post id: 1, ...>
200
- Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
201
- Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
202
- end
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)
203
410
  ```
204
411
 
205
- Fixes #34638, #35398.
412
+ The above now works as expected.
206
413
 
207
- *Ryuta Kamizono*
414
+ *fatkodima*
208
415
 
209
- * Add `rails db:prepare` to migrate or setup a database.
416
+ * Properly release pinned connections with non joinable connections.
210
417
 
211
- Runs `db:migrate` if the database exists or `db:setup` if it doesn't.
418
+ Fixes #52973
212
419
 
213
- *Roberto Miranda*
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.
214
423
 
215
- * Add `after_save_commit` callback as shortcut for `after_commit :hook, on: [ :create, :update ]`.
424
+ *Jean Boussier*
216
425
 
217
- *DHH*
426
+ * Make Float distinguish between `float4` and `float8` in PostgreSQL.
218
427
 
219
- * Assign all attributes before calling `build` to ensure the child record is visible in
220
- `before_add` and `after_add` callbacks for `has_many :through` associations.
428
+ Fixes #52742
221
429
 
222
- Fixes #33249.
430
+ *Ryota Kitazawa*, *Takayuki Nagatomi*
223
431
 
224
- *Ryan H. Kerr*
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.
225
434
 
226
- * Add `ActiveRecord::Relation#extract_associated` for extracting associated records from a relation.
435
+ Previously, using `.left_outer_joins` with the same child association would only join one of the parents.
227
436
 
228
- ```
229
- account.memberships.extract_associated(:user)
230
- # => Returns collection of User records
231
- ```
437
+ Now it will correctly join both parents.
232
438
 
233
- *DHH*
439
+ Fixes #41498.
234
440
 
235
- * Add `ActiveRecord::Relation#annotate` for adding SQL comments to its queries.
441
+ *Garrett Blehm*
236
442
 
237
- For example:
443
+ * Ensure `ActiveRecord::Encryption.config` is always ready before access.
238
444
 
239
- ```
240
- Post.where(id: 123).annotate("this is a comment").to_sql
241
- # SELECT "posts".* FROM "posts" WHERE "posts"."id" = 123 /* this is a comment */
242
- ```
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.
243
448
 
244
- This can be useful in instrumentation or other analysis of issued queries.
449
+ `ActiveRecord::Encryption` now has its own loading hook so that its configuration is set as
450
+ soon as needed.
245
451
 
246
- *Matt Yoho*
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`.
247
455
 
248
- * Support Optimizer Hints.
456
+ *Maxime Réty*
249
457
 
250
- In most databases, a way to control the optimizer is by using optimizer hints,
251
- which can be specified within individual statements.
458
+ * Add `TimeZoneConverter#==` method, so objects will be properly compared by
459
+ their type, scale, limit & precision.
252
460
 
253
- Example (for MySQL):
461
+ Address #52699.
254
462
 
255
- Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
256
- # SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
463
+ *Ruy Rocha*
257
464
 
258
- Example (for PostgreSQL with pg_hint_plan):
259
465
 
260
- Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
261
- # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
466
+ ## Rails 7.2.1.2 (October 23, 2024) ##
262
467
 
263
- See also:
468
+ * No changes.
264
469
 
265
- * https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html
266
- * https://pghintplan.osdn.jp/pg_hint_plan.html
267
- * https://docs.oracle.com/en/database/oracle/oracle-database/12.2/tgsql/influencing-the-optimizer.html
268
- * https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-2017
269
- * https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.admin.perf.doc/doc/c0070117.html
270
470
 
271
- *Ryuta Kamizono*
471
+ ## Rails 7.2.1.1 (October 15, 2024) ##
272
472
 
273
- * Fix query attribute method on user-defined attribute to be aware of typecasted value.
473
+ * No changes.
274
474
 
275
- For example, the following code no longer return false as casted non-empty string:
276
475
 
277
- ```
278
- class Post < ActiveRecord::Base
279
- attribute :user_defined_text, :text
280
- end
476
+ ## Rails 7.2.1 (August 22, 2024) ##
281
477
 
282
- Post.new(user_defined_text: "false").user_defined_text? # => true
283
- ```
478
+ * Fix detection for `enum` columns with parallelized tests and PostgreSQL.
284
479
 
285
- *Yuji Kamijima*
480
+ *Rafael Mendonça França*
286
481
 
287
- * Quote empty ranges like other empty enumerables.
482
+ * Allow to eager load nested nil associations.
288
483
 
289
- *Patrick Rebsch*
484
+ *fatkodima*
290
485
 
291
- * Add `insert_all`/`insert_all!`/`upsert_all` methods to `ActiveRecord::Persistence`,
292
- allowing bulk inserts akin to the bulk updates provided by `update_all` and
293
- bulk deletes by `delete_all`.
486
+ * Fix swallowing ignore order warning when batching using `BatchEnumerator`.
294
487
 
295
- Supports skipping or upserting duplicates through the `ON CONFLICT` syntax
296
- for PostgreSQL (9.5+) and SQLite (3.24+) and `ON DUPLICATE KEY UPDATE` syntax
297
- for MySQL.
488
+ *fatkodima*
298
489
 
299
- *Bob Lail*
490
+ * Fix memory bloat on the connection pool when using the Fiber `IsolatedExecutionState`.
300
491
 
301
- * Add `rails db:seed:replant` that truncates tables of each database
302
- for current environment and loads the seeds.
492
+ *Jean Boussier*
303
493
 
304
- *bogdanvlviv*, *DHH*
494
+ * Restore inferred association class with the same modularized name.
305
495
 
306
- * Add `ActiveRecord::Base.connection.truncate` for SQLite3 adapter.
496
+ *Justin Ko*
307
497
 
308
- *bogdanvlviv*
498
+ * Fix `ActiveRecord::Base.inspect` to properly explain how to load schema information.
309
499
 
310
- * Deprecate mismatched collation comparison for uniqueness validator.
500
+ *Jean Boussier*
311
501
 
312
- Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1.
313
- To continue case sensitive comparison on the case insensitive column,
314
- pass `case_sensitive: true` option explicitly to the uniqueness validator.
502
+ * Check invalid `enum` options for the new syntax.
315
503
 
316
- *Ryuta Kamizono*
504
+ The options using `_` prefix in the old syntax are invalid in the new syntax.
317
505
 
318
- * Add `reselect` method. This is a short-hand for `unscope(:select).select(fields)`.
506
+ *Rafael Mendonça França*
319
507
 
320
- Fixes #27340.
508
+ * Fix `ActiveRecord::Encryption::EncryptedAttributeType#type` to return
509
+ actual cast type.
321
510
 
322
- *Willian Gustavo Veiga*
511
+ *Vasiliy Ermolovich*
323
512
 
324
- * Add negative scopes for all enum values.
513
+ * Fix `create_table` with `:auto_increment` option for MySQL adapter.
325
514
 
326
- Example:
515
+ *fatkodima*
327
516
 
328
- class Post < ActiveRecord::Base
329
- enum status: %i[ drafted active trashed ]
330
- end
331
517
 
332
- Post.not_drafted # => where.not(status: :drafted)
333
- Post.not_active # => where.not(status: :active)
334
- Post.not_trashed # => where.not(status: :trashed)
518
+ ## Rails 7.2.0 (August 09, 2024) ##
335
519
 
336
- *DHH*
520
+ * Handle commas in Sqlite3 default function definitions.
337
521
 
338
- * Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
522
+ *Stephen Margheim*
339
523
 
340
- Fixes #35214.
524
+ * Fixes `validates_associated` raising an exception when configured with a
525
+ singular association and having `index_nested_attribute_errors` enabled.
341
526
 
342
- *Juani Villarejo*
527
+ *Martin Spickermann*
343
528
 
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.
344
532
 
345
- ## Rails 6.0.0.beta3 (March 11, 2019) ##
533
+ *Xavier Noria*
346
534
 
347
- * No changes.
535
+ * Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
536
+ `DatabaseConfig`.
348
537
 
538
+ *Hartley McGuire*
349
539
 
350
- ## Rails 6.0.0.beta2 (February 25, 2019) ##
540
+ * Fixed a memory performance issue in Active Record attribute methods definition.
351
541
 
352
- * Fix prepared statements caching to be enabled even when query caching is enabled.
542
+ *Jean Boussier*
353
543
 
354
- *Ryuta Kamizono*
544
+ * Define the new Active Support notification event `start_transaction.active_record`.
355
545
 
356
- * Ensure `update_all` series cares about optimistic locking.
546
+ This event is fired when database transactions or savepoints start, and
547
+ complements `transaction.active_record`, which is emitted when they finish.
357
548
 
358
- *Ryuta Kamizono*
549
+ The payload has the transaction (`:transaction`) and the connection (`:connection`).
359
550
 
360
- * Don't allow `where` with non numeric string matches to 0 values.
551
+ *Xavier Noria*
361
552
 
362
- *Ryuta Kamizono*
553
+ * Fix an issue where the IDs reader method did not return expected results
554
+ for preloaded associations in models using composite primary keys.
363
555
 
364
- * Introduce `ActiveRecord::Relation#destroy_by` and `ActiveRecord::Relation#delete_by`.
556
+ *Jay Ang*
365
557
 
366
- `destroy_by` allows relation to find all the records matching the condition and perform
367
- `destroy_all` on the matched records.
558
+ * The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
368
559
 
369
- Example:
560
+ *Xavier Noria*
370
561
 
371
- Person.destroy_by(name: 'David')
372
- Person.destroy_by(name: 'David', rating: 4)
562
+ * The payload of `transaction.active_record` Active Support notifications now has the transaction the event is related to in the `:transaction` key.
373
563
 
374
- david = Person.find_by(name: 'David')
375
- david.posts.destroy_by(id: [1, 2, 3])
564
+ *Xavier Noria*
376
565
 
377
- `delete_by` allows relation to find all the records matching the condition and perform
378
- `delete_all` on the matched records.
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.
379
567
 
380
- Example:
568
+ *Xavier Noria*
381
569
 
382
- Person.delete_by(name: 'David')
383
- Person.delete_by(name: 'David', rating: 4)
570
+ * Fix inference of association model on nested models with the same demodularized name.
384
571
 
385
- david = Person.find_by(name: 'David')
386
- david.posts.delete_by(id: [1, 2, 3])
572
+ E.g. with the following setup:
387
573
 
388
- *Abhay Nikam*
574
+ ```ruby
575
+ class Nested::Post < ApplicationRecord
576
+ has_one :post, through: :other
577
+ end
578
+ ```
389
579
 
390
- * Don't allow `where` with invalid value matches to nil values.
580
+ Before, `#post` would infer the model as `Nested::Post`, but now it correctly infers `Post`.
391
581
 
392
- Fixes #33624.
582
+ *Joshua Young*
393
583
 
394
- *Ryuta Kamizono*
584
+ * PostgreSQL `Cidr#change?` detects the address prefix change.
395
585
 
396
- * SQLite3: Implement `add_foreign_key` and `remove_foreign_key`.
586
+ *Taketo Takashima*
397
587
 
398
- *Ryuta Kamizono*
588
+ * Change `BatchEnumerator#destroy_all` to return the total number of affected rows.
399
589
 
400
- * Deprecate using class level querying methods if the receiver scope
401
- regarded as leaked. Use `klass.unscoped` to avoid the leaking scope.
590
+ Previously, it always returned `nil`.
402
591
 
403
- *Ryuta Kamizono*
592
+ *fatkodima*
593
+
594
+ * Support `touch_all` in batches.
595
+
596
+ ```ruby
597
+ Post.in_batches.touch_all
598
+ ```
599
+
600
+ *fatkodima*
404
601
 
405
- * Allow applications to automatically switch connections.
602
+ * Add support for `:if_not_exists` and `:force` options to `create_schema`.
406
603
 
407
- Adds a middleware and configuration options that can be used in your
408
- application to automatically switch between the writing and reading
409
- database connections.
604
+ *fatkodima*
410
605
 
411
- `GET` and `HEAD` requests will read from the replica unless there was
412
- a write in the last 2 seconds, otherwise they will read from the primary.
413
- Non-get requests will always write to the primary. The middleware accepts
414
- an argument for a Resolver class and an Operations class where you are able
415
- to change how the auto-switcher works to be most beneficial for your
416
- application.
606
+ * Fix `index_errors` having incorrect index in association validation errors.
607
+
608
+ *lulalala*
609
+
610
+ * Add `index_errors: :nested_attributes_order` mode.
611
+
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.
613
+
614
+ *lulalala*
615
+
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.
617
+
618
+ *Joé Dupuis*
619
+
620
+ * Association option `query_constraints` is deprecated in favor of `foreign_key`.
621
+
622
+ *Nikita Vasilevsky*
623
+
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.
625
+
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.
627
+
628
+ *DHH*
417
629
 
418
- To use the middleware in your application you can use the following
419
- configuration options:
630
+ * Added support for recursive common table expressions.
420
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
+ )
421
639
  ```
422
- config.active_record.database_selector = { delay: 2.seconds }
423
- config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
424
- config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
640
+
641
+ Generates the following SQL:
642
+
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"
425
650
  ```
426
651
 
427
- To change the database selection strategy, pass a custom class to the
428
- configuration options:
652
+ *ClearlyClaire*
429
653
 
654
+ * `validate_constraint` can be called in a `change_table` block.
655
+
656
+ ex:
657
+ ```ruby
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
430
662
  ```
431
- config.active_record.database_selector = { delay: 10.seconds }
432
- config.active_record.database_resolver = MyResolver
433
- config.active_record.database_resolver_context = MyResolver::MyCookies
663
+
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
434
672
  ```
435
673
 
436
- *Eileen M. Uchitelle*
674
+ *Joé Dupuis*
437
675
 
438
- * MySQL: Support `:size` option to change text and blob size.
676
+ * Strict loading using `:n_plus_one_only` does not eagerly load child associations.
439
677
 
440
- *Ryuta Kamizono*
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.
441
683
 
442
- * Make `t.timestamps` with precision by default.
684
+ Before:
443
685
 
444
- *Ryuta Kamizono*
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
+ ```
445
693
 
694
+ After:
446
695
 
447
- ## Rails 6.0.0.beta1 (January 18, 2019) ##
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
+ ```
448
703
 
449
- * Remove deprecated `#set_state` from the transaction object.
704
+ *Reid Lynch*
450
705
 
451
- *Rafael Mendonça França*
706
+ * Allow `Sqlite3Adapter` to use `sqlite3` gem version `2.x`.
452
707
 
453
- * Remove deprecated `#supports_statement_cache?` from the database adapters.
708
+ *Mike Dalessio*
454
709
 
455
- *Rafael Mendonça França*
710
+ * Allow `ActiveRecord::Base#pluck` to accept hash values.
456
711
 
457
- * Remove deprecated `#insert_fixtures` from the database adapters.
712
+ ```ruby
713
+ # Before
714
+ Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
458
715
 
459
- *Rafael Mendonça França*
716
+ # After
717
+ Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
718
+ ```
460
719
 
461
- * Remove deprecated `ActiveRecord::ConnectionAdapters::SQLite3Adapter#valid_alter_table_type?`.
720
+ *fatkodima*
462
721
 
463
- *Rafael Mendonça França*
722
+ * Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
464
723
 
465
- * Do not allow passing the column name to `sum` when a block is passed.
724
+ *Kevin McPhillips*
466
725
 
467
- *Rafael Mendonça França*
726
+ * `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transaction` object.
727
+
728
+ This allows to register callbacks on it.
729
+
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
+ ```
738
+
739
+ *Jean Boussier*
740
+
741
+ * Add `ActiveRecord::Base.current_transaction`.
742
+
743
+ Returns the current transaction, to allow registering callbacks on it.
744
+
745
+ ```ruby
746
+ Article.current_transaction.after_commit do
747
+ PublishNotificationMailer.with(article: article).deliver_later
748
+ end
749
+ ```
750
+
751
+ *Jean Boussier*
752
+
753
+ * Add `ActiveRecord.after_all_transactions_commit` callback.
754
+
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.
757
+
758
+ ```ruby
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
764
+ end
765
+ ```
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
+
772
+ *Jean Boussier*
773
+
774
+ * Add the ability to ignore counter cache columns until they are backfilled.
775
+
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.
782
+
783
+ Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:
784
+
785
+ ```ruby
786
+ class Comment < ApplicationRecord
787
+ belongs_to :post, counter_cache: { active: false }
788
+ end
789
+ ```
790
+
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.
795
+
796
+ *fatkodima*
797
+
798
+ * Retry known idempotent SELECT queries on connection-related exceptions.
799
+
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.
804
+
805
+ *Adrianna Chang*
806
+
807
+ * Allow association's `foreign_key` to be composite.
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.
811
+
812
+ *Nikita Vasilevsky*
813
+
814
+ * Allow association's `primary_key` to be composite.
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.
818
+
819
+ *Nikita Vasilevsky*
820
+
821
+ * Add `config.active_record.permanent_connection_checkout` setting.
468
822
 
469
- * Do not allow passing the column name to `count` when a block is passed.
823
+ Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.
824
+
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.
828
+
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.
831
+
832
+ The default behavior remains unchanged, and there is currently no plans to change the default.
833
+
834
+ *Jean Boussier*
835
+
836
+ * Add dirties option to uncached.
837
+
838
+ This adds a `dirties` option to `ActiveRecord::Base.uncached` and
839
+ `ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.
840
+
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.
843
+
844
+ This is needed by Solid Cache so that cache writes do not clear query caches.
845
+
846
+ *Donal McBreen*
847
+
848
+ * Deprecate `ActiveRecord::Base.connection` in favor of `.lease_connection`.
849
+
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.
852
+
853
+ This deprecation is a soft deprecation, no warnings will be issued and there is no
854
+ current plan to remove the method.
855
+
856
+ *Jean Boussier*
857
+
858
+ * Deprecate `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
859
+
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.
862
+
863
+ *Jean Boussier*
864
+
865
+ * Expose a generic fixture accessor for fixture names that may conflict with Minitest.
866
+
867
+ ```ruby
868
+ assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
869
+ assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
870
+ ```
871
+
872
+ *Jean Boussier*
873
+
874
+ * Using `Model.query_constraints` with a single non-primary-key column used to raise as expected, but with an
875
+ incorrect error message.
876
+
877
+ This has been fixed to raise with a more appropriate error message.
878
+
879
+ *Joshua Young*
880
+
881
+ * Fix `has_one` association autosave setting the foreign key attribute when it is unchanged.
882
+
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.
885
+
886
+ *Joshua Young*
887
+
888
+ * Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`.
470
889
 
471
890
  *Rafael Mendonça França*
472
891
 
473
- * Remove delegation of missing methods in a relation to arel.
892
+ * Deprecate `Rails.application.config.active_record.commit_transaction_on_non_local_return`.
474
893
 
475
894
  *Rafael Mendonça França*
476
895
 
477
- * Remove delegation of missing methods in a relation to private methods of the class.
896
+ * Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge`.
478
897
 
479
898
  *Rafael Mendonça França*
480
899
 
481
- * Deprecate `config.activerecord.sqlite3.represent_boolean_as_integer`.
900
+ * Remove deprecated support to pass `deferrable: true` to `add_foreign_key`.
482
901
 
483
902
  *Rafael Mendonça França*
484
903
 
485
- * Change `SQLite3Adapter` to always represent boolean values as integers.
904
+ * Remove deprecated support to quote `ActiveSupport::Duration`.
486
905
 
487
906
  *Rafael Mendonça França*
488
907
 
489
- * Remove ability to specify a timestamp name for `#cache_key`.
908
+ * Remove deprecated `#quote_bound_value`.
490
909
 
491
910
  *Rafael Mendonça França*
492
911
 
493
- * Remove deprecated `ActiveRecord::Migrator.migrations_path=`.
912
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass`.
494
913
 
495
914
  *Rafael Mendonça França*
496
915
 
497
- * Remove deprecated `expand_hash_conditions_for_aggregates`.
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.
498
919
 
499
920
  *Rafael Mendonça França*
500
921
 
501
- * Set polymorphic type column to NULL on `dependent: :nullify` strategy.
922
+ * Remove deprecated `#all_connection_pools`.
502
923
 
503
- On polymorphic associations both the foreign key and the foreign type columns will be set to NULL.
924
+ *Rafael Mendonça França*
504
925
 
505
- *Laerti Papa*
926
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache#data_sources`.
506
927
 
507
- * Allow permitted instance of `ActionController::Parameters` as argument of `ActiveRecord::Relation#exists?`.
928
+ *Rafael Mendonça França*
508
929
 
509
- *Gannon McGibbon*
930
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::SchemaCache.load_from`.
510
931
 
511
- * Add support for endless ranges introduces in Ruby 2.6.
932
+ *Rafael Mendonça França*
512
933
 
513
- *Greg Navis*
934
+ * Remove deprecated `#all_foreign_keys_valid?` from database adapters.
514
935
 
515
- * Deprecate passing `migrations_paths` to `connection.assume_migrated_upto_version`.
936
+ *Rafael Mendonça França*
516
937
 
517
- *Ryuta Kamizono*
938
+ * Remove deprecated support to passing coder and class as second argument to `serialize`.
518
939
 
519
- * MySQL: `ROW_FORMAT=DYNAMIC` create table option by default.
940
+ *Rafael Mendonça França*
520
941
 
521
- Since MySQL 5.7.9, the `innodb_default_row_format` option defines the default row
522
- format for InnoDB tables. The default setting is `DYNAMIC`.
523
- The row format is required for indexing on `varchar(255)` with `utf8mb4` columns.
942
+ * Remove deprecated support to `ActiveRecord::Base#read_attribute(:id)` to return the custom primary key value.
524
943
 
525
- *Ryuta Kamizono*
944
+ *Rafael Mendonça França*
526
945
 
527
- * Fix join table column quoting with SQLite.
946
+ * Remove deprecated `TestFixtures.fixture_path`.
528
947
 
529
- *Gannon McGibbon*
948
+ *Rafael Mendonça França*
530
949
 
531
- * Allow disabling scopes generated by `ActiveRecord.enum`.
950
+ * Remove deprecated behavior to support referring to a singular association by its plural name.
532
951
 
533
- *Alfred Dominic*
952
+ *Rafael Mendonça França*
534
953
 
535
- * Ensure that `delete_all` on collection proxy returns affected count.
954
+ * Deprecate `Rails.application.config.active_record.allow_deprecated_singular_associations_name`.
536
955
 
537
- *Ryuta Kamizono*
956
+ *Rafael Mendonça França*
538
957
 
539
- * Reset scope after delete on collection association to clear stale offsets of removed records.
958
+ * Remove deprecated support to passing `SchemaMigration` and `InternalMetadata` classes as arguments to
959
+ `ActiveRecord::MigrationContext`.
540
960
 
541
- *Gannon McGibbon*
961
+ *Rafael Mendonça França*
542
962
 
543
- * Add the ability to prevent writes to a database for the duration of a block.
963
+ * Remove deprecated `ActiveRecord::Migration.check_pending!` method.
544
964
 
545
- Allows the application to prevent writes to a database. This can be useful when
546
- you're building out multiple databases and want to make sure you're not sending
547
- writes when you want a read.
965
+ *Rafael Mendonça França*
548
966
 
549
- If `while_preventing_writes` is called and the query is considered a write
550
- query the database will raise an exception regardless of whether the database
551
- user is able to write.
967
+ * Remove deprecated `ActiveRecord::LogSubscriber.runtime` method.
552
968
 
553
- This is not meant to be a catch-all for write queries but rather a way to enforce
554
- read-only queries without opening a second connection. One purpose of this is to
555
- catch accidental writes, not all writes.
969
+ *Rafael Mendonça França*
556
970
 
557
- *Eileen M. Uchitelle*
971
+ * Remove deprecated `ActiveRecord::LogSubscriber.runtime=` method.
558
972
 
559
- * Allow aliased attributes to be used in `#update_columns` and `#update`.
973
+ *Rafael Mendonça França*
560
974
 
561
- *Gannon McGibbon*
975
+ * Remove deprecated `ActiveRecord::LogSubscriber.reset_runtime` method.
562
976
 
563
- * Allow spaces in postgres table names.
977
+ *Rafael Mendonça França*
564
978
 
565
- Fixes issue where "user post" is misinterpreted as "\"user\".\"post\"" when quoting table names with the postgres adapter.
979
+ * Remove deprecated support to define `explain` in the connection adapter with 2 arguments.
566
980
 
567
- *Gannon McGibbon*
981
+ *Rafael Mendonça França*
568
982
 
569
- * Cached `columns_hash` fields should be excluded from `ResultSet#column_types`.
983
+ * Remove deprecated `ActiveRecord::ActiveJobRequiredError`.
570
984
 
571
- PR #34528 addresses the inconsistent behaviour when attribute is defined for an ignored column. The following test
572
- was passing for SQLite and MySQL, but failed for PostgreSQL:
985
+ *Rafael Mendonça França*
573
986
 
574
- ```ruby
575
- class DeveloperName < ActiveRecord::Type::String
576
- def deserialize(value)
577
- "Developer: #{value}"
578
- end
579
- end
987
+ * Remove deprecated `ActiveRecord::Base.clear_active_connections!`.
580
988
 
581
- class AttributedDeveloper < ActiveRecord::Base
582
- self.table_name = "developers"
989
+ *Rafael Mendonça França*
583
990
 
584
- attribute :name, DeveloperName.new
991
+ * Remove deprecated `ActiveRecord::Base.clear_reloadable_connections!`.
585
992
 
586
- self.ignored_columns += ["name"]
587
- end
993
+ *Rafael Mendonça França*
588
994
 
589
- developer = AttributedDeveloper.create
590
- developer.update_column :name, "name"
995
+ * Remove deprecated `ActiveRecord::Base.clear_all_connections!`.
591
996
 
592
- loaded_developer = AttributedDeveloper.where(id: developer.id).select("*").first
593
- puts loaded_developer.name # should be "Developer: name" but it's just "name"
594
- ```
997
+ *Rafael Mendonça França*
595
998
 
596
- *Dmitry Tsepelev*
999
+ * Remove deprecated `ActiveRecord::Base.flush_idle_connections!`.
597
1000
 
598
- * Make the implicit order column configurable.
1001
+ *Rafael Mendonça França*
599
1002
 
600
- When calling ordered finder methods such as `first` or `last` without an
601
- explicit order clause, ActiveRecord sorts records by primary key. This can
602
- result in unpredictable and surprising behaviour when the primary key is
603
- not an auto-incrementing integer, for example when it's a UUID. This change
604
- makes it possible to override the column used for implicit ordering such
605
- that `first` and `last` will return more predictable results.
1003
+ * Remove deprecated `name` argument from `ActiveRecord::Base.remove_connection`.
606
1004
 
607
- Example:
1005
+ *Rafael Mendonça França*
608
1006
 
609
- class Project < ActiveRecord::Base
610
- self.implicit_order_column = "created_at"
611
- end
1007
+ * Remove deprecated support to call `alias_attribute` with non-existent attribute names.
612
1008
 
613
- *Tekin Suleyman*
1009
+ *Rafael Mendonça França*
614
1010
 
615
- * Bump minimum PostgreSQL version to 9.3.
1011
+ * Remove deprecated `Rails.application.config.active_record.suppress_multiple_database_warning`.
616
1012
 
617
- *Yasuo Honda*
1013
+ *Rafael Mendonça França*
618
1014
 
619
- * Values of enum are frozen, raising an error when attempting to modify them.
1015
+ * Add `ActiveRecord::Encryption::MessagePackMessageSerializer`.
620
1016
 
621
- *Emmanuel Byrd*
1017
+ Serialize data to the MessagePack format, for efficient storage in binary columns.
622
1018
 
623
- * Move `ActiveRecord::StatementInvalid` SQL to error property and include binds as separate error property.
1019
+ The binary encoding requires around 30% less space than the base64 encoding
1020
+ used by the default serializer.
624
1021
 
625
- `ActiveRecord::ConnectionAdapters::AbstractAdapter#translate_exception_class` now requires `binds` to be passed as the last argument.
1022
+ *Donal McBreen*
626
1023
 
627
- `ActiveRecord::ConnectionAdapters::AbstractAdapter#translate_exception` now requires `message`, `sql`, and `binds` to be passed as keyword arguments.
1024
+ * Add support for encrypting binary columns.
628
1025
 
629
- Subclasses of `ActiveRecord::StatementInvalid` must now provide `sql:` and `binds:` arguments to `super`.
1026
+ Ensure encryption and decryption pass `Type::Binary::Data` around for binary data.
630
1027
 
631
- Example:
1028
+ Previously encrypting binary columns with the `ActiveRecord::Encryption::MessageSerializer`
1029
+ incidentally worked for MySQL and SQLite, but not PostgreSQL.
632
1030
 
633
- ```
634
- class MySubclassedError < ActiveRecord::StatementInvalid
635
- def initialize(message, sql:, binds:)
636
- super(message, sql: sql, binds: binds)
637
- end
638
- end
639
- ```
1031
+ *Donal McBreen*
640
1032
 
641
- *Gannon McGibbon*
1033
+ * Deprecated `ENV["SCHEMA_CACHE"]` in favor of `schema_cache_path` in the database configuration.
642
1034
 
643
- * Add an `:if_not_exists` option to `create_table`.
1035
+ *Rafael Mendonça França*
644
1036
 
645
- Example:
1037
+ * Add `ActiveRecord::Base.with_connection` as a shortcut for leasing a connection for a short duration.
646
1038
 
647
- create_table :posts, if_not_exists: true do |t|
648
- t.string :title
649
- end
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.
650
1041
 
651
- That would execute:
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.
652
1044
 
653
- CREATE TABLE IF NOT EXISTS posts (
654
- ...
655
- )
1045
+ *Jean Boussier*
656
1046
 
657
- If the table already exists, `if_not_exists: false` (the default) raises an
658
- exception whereas `if_not_exists: true` does nothing.
1047
+ * Deprecate `config.active_record.warn_on_records_fetched_greater_than` now that `sql.active_record`
1048
+ notification includes `:row_count` field.
659
1049
 
660
- *fatkodima*, *Stefan Kanev*
1050
+ *Jason Nochlin*
661
1051
 
662
- * Defining an Enum as a Hash with blank key, or as an Array with a blank value, now raises an `ArgumentError`.
1052
+ * Fix an issue with `where.associated` losing the current join type scope.
663
1053
 
664
- *Christophe Maximin*
1054
+ Example:
665
1055
 
666
- * Adds support for multiple databases to `rails db:schema:cache:dump` and `rails db:schema:cache:clear`.
1056
+ ```ruby
1057
+ Post.left_joins(:author).where.associated(:author)
1058
+ ```
667
1059
 
668
- *Gannon McGibbon*
1060
+ Previously, the `LEFT OUTER JOIN` would be lost and converted to an `INNER JOIN`.
669
1061
 
670
- * `update_columns` now correctly raises `ActiveModel::MissingAttributeError`
671
- if the attribute does not exist.
1062
+ *Saleh Alhaddad*
672
1063
 
673
- *Sean Griffin*
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.
674
1067
 
675
- * Add support for hash and URL configs in database hash of `ActiveRecord::Base.connected_to`.
1068
+ *Maxime Réty*
676
1069
 
677
- ````
678
- User.connected_to(database: { writing: "postgres://foo" }) do
679
- User.create!(name: "Gannon")
680
- end
1070
+ * Deprecate defining an `enum` with keyword arguments.
681
1071
 
682
- config = { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" }
683
- User.connected_to(database: { reading: config }) do
684
- User.count
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]
685
1081
  end
686
- ````
1082
+ ```
687
1083
 
688
- *Gannon McGibbon*
1084
+ *Hartley McGuire*
689
1085
 
690
- * Support default expression for MySQL.
1086
+ * Add `config.active_record.validate_migration_timestamps` option for validating migration timestamps.
691
1087
 
692
- MySQL 8.0.13 and higher supports default value to be a function or expression.
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.
693
1092
 
694
- https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1093
+ *Adrianna Chang*
695
1094
 
696
- *Ryuta Kamizono*
1095
+ * Properly synchronize `Mysql2Adapter#active?` and `TrilogyAdapter#active?`.
697
1096
 
698
- * Support expression indexes for MySQL.
1097
+ As well as `disconnect!` and `verify!`.
699
1098
 
700
- MySQL 8.0.13 and higher supports functional key parts that index
701
- expression values rather than column or column prefix values.
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.
702
1102
 
703
- https://dev.mysql.com/doc/refman/8.0/en/create-index.html
1103
+ *Jean Boussier*
704
1104
 
705
- *Ryuta Kamizono*
1105
+ * Support `:source_location` tag option for query log tags.
706
1106
 
707
- * Fix collection cache key with limit and custom select to avoid ambiguous timestamp column error.
1107
+ ```ruby
1108
+ config.active_record.query_log_tags << :source_location
1109
+ ```
708
1110
 
709
- Fixes #33056.
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.
710
1114
 
711
- *Federico Martinez*
1115
+ *fatkodima*
712
1116
 
713
- * Add basic API for connection switching to support multiple databases.
1117
+ * Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression.
714
1118
 
715
- 1) Adds a `connects_to` method for models to connect to multiple databases. Example:
1119
+ Allow compression to be disabled by setting `compress: false`
716
1120
 
1121
+ ```ruby
1122
+ class User
1123
+ encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
1124
+ end
717
1125
  ```
718
- class AnimalsModel < ApplicationRecord
719
- self.abstract_class = true
720
1126
 
721
- connects_to database: { writing: :animals_primary, reading: :animals_replica }
722
- end
1127
+ *Donal McBreen*
723
1128
 
724
- class Dog < AnimalsModel
725
- # connected to both the animals_primary db for writing and the animals_replica for reading
726
- end
727
- ```
1129
+ * Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
728
1130
 
729
- 2) Adds a `connected_to` block method for switching connection roles or connecting to
730
- a database that the model didn't connect to. Connecting to the database in this block is
731
- useful when you have another defined connection, for example `slow_replica` that you don't
732
- want to connect to by default but need in the console, or a specific code block.
1131
+ A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
733
1132
 
734
- ```
735
- ActiveRecord::Base.connected_to(role: :reading) do
736
- Dog.first # finds dog from replica connected to AnimalsBase
737
- Book.first # doesn't have a reading connection, will raise an error
738
- end
739
- ```
1133
+ *Rafael Mendonça França*
740
1134
 
741
- ```
742
- ActiveRecord::Base.connected_to(database: :slow_replica) do
743
- SlowReplicaModel.first # if the db config has a slow_replica configuration this will be used to do the lookup, otherwise this will throw an exception
744
- end
745
- ```
1135
+ * Add `row_count` field to `sql.active_record` notification.
746
1136
 
747
- *Eileen M. Uchitelle*
1137
+ This field returns the amount of rows returned by the query that emitted the notification.
748
1138
 
749
- * Enum raises on invalid definition values
1139
+ This metric is useful in cases where one wants to detect queries with big result sets.
750
1140
 
751
- When defining a Hash enum it can be easy to use `[]` instead of `{}`. This
752
- commit checks that only valid definition values are provided, those can
753
- be a Hash, an array of Symbols or an array of Strings. Otherwise it
754
- raises an `ArgumentError`.
1141
+ *Marvin Bitterlich*
755
1142
 
756
- Fixes #33961
1143
+ * Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
757
1144
 
758
- *Alberto Almagro*
1145
+ Previously, this would only raise on collection associations and produce a generic error on singular associations.
759
1146
 
760
- * Reloading associations now clears the Query Cache like `Persistence#reload` does.
1147
+ Now, it will raise on both collection and singular associations.
761
1148
 
762
- ```
763
- class Post < ActiveRecord::Base
764
- has_one :category
765
- belongs_to :author
766
- has_many :comments
767
- end
1149
+ *Joshua Young*
768
1150
 
769
- # Each of the following will now clear the query cache.
770
- post.reload_category
771
- post.reload_author
772
- post.comments.reload
773
- ```
1151
+ * Fix single quote escapes on default generated MySQL columns.
774
1152
 
775
- *Christophe Maximin*
1153
+ MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
776
1154
 
777
- * Added `index` option for `change_table` migration helpers.
778
- With this change you can create indexes while adding new
779
- columns into the existing tables.
1155
+ Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
780
1156
 
781
- Example:
1157
+ This would result in issues when importing the schema on a fresh instance of a MySQL database.
782
1158
 
783
- change_table(:languages) do |t|
784
- t.string :country_code, index: true
785
- end
786
-
787
- *Mehmet Emin İNAÇ*
1159
+ Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
788
1160
 
789
- * Fix `transaction` reverting for migrations.
1161
+ *Yash Kapadia*
790
1162
 
791
- Before: Commands inside a `transaction` in a reverted migration ran uninverted.
792
- Now: This change fixes that by reverting commands inside `transaction` block.
1163
+ * Fix Migrations with versions older than 7.1 validating options given to
1164
+ `add_reference` and `t.references`.
793
1165
 
794
- *fatkodima*, *David Verhasselt*
1166
+ *Hartley McGuire*
795
1167
 
796
- * Raise an error instead of scanning the filesystem root when `fixture_path` is blank.
1168
+ * Add `<role>_types` class method to `ActiveRecord::DelegatedType` so that the delegated types can be introspected.
797
1169
 
798
- *Gannon McGibbon*, *Max Albrecht*
1170
+ *JP Rosevear*
799
1171
 
800
- * Allow `ActiveRecord::Base.configurations=` to be set with a symbolized hash.
1172
+ * Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL`.
801
1173
 
802
- *Gannon McGibbon*
1174
+ This wouldn't always work previously because boolean values would be interpreted as strings.
803
1175
 
804
- * Don't update counter cache unless the record is actually saved.
1176
+ e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema
1177
+ cache.
805
1178
 
806
- Fixes #31493, #33113, #33117.
1179
+ *Mike Coutermarsh*, *Jean Boussier*
807
1180
 
808
- *Ryuta Kamizono*
1181
+ * Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`.
809
1182
 
810
- * Deprecate `ActiveRecord::Result#to_hash` in favor of `ActiveRecord::Result#to_a`.
1183
+ It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
1184
+ but with support for `after_commit` and `after_rollback` callback options.
811
1185
 
812
- *Gannon McGibbon*, *Kevin Cheng*
1186
+ *Joshua Young*
813
1187
 
814
- * SQLite3 adapter supports expression indexes.
1188
+ * Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
815
1189
 
816
- ```
817
- create_table :users do |t|
818
- t.string :email
819
- end
1190
+ Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
820
1191
 
821
- add_index :users, 'lower(email)', name: 'index_users_on_email', unique: true
822
- ```
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`.
823
1193
 
824
- *Gray Kemmey*
1194
+ The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.
825
1195
 
826
- * Allow subclasses to redefine autosave callbacks for associated records.
1196
+ *Maxime Réty*
827
1197
 
828
- Fixes #33305.
1198
+ * Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.
829
1199
 
830
- *Andrey Subbota*
1200
+ *Maxime Réty*
831
1201
 
832
- * Bump minimum MySQL version to 5.5.8.
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:
833
1205
 
834
- *Yasuo Honda*
1206
+ ```ruby
1207
+ User.all.explain.count
1208
+ # EXPLAIN SELECT COUNT(*) FROM `users`
1209
+ # ...
835
1210
 
836
- * Use MySQL utf8mb4 character set by default.
1211
+ User.all.explain.maximum(:id)
1212
+ # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
1213
+ # ...
1214
+ ```
837
1215
 
838
- `utf8mb4` character set with 4-Byte encoding supports supplementary characters including emoji.
839
- The previous default 3-Byte encoding character set `utf8` is not enough to support them.
1216
+ *Petrik de Heus*
840
1217
 
841
- *Yasuo Honda*
1218
+ * Fixes an issue where `validates_associated` `:on` option wasn't respected
1219
+ when validating associated records.
842
1220
 
843
- * Fix duplicated record creation when using nested attributes with `create_with`.
1221
+ *Austen Madden*, *Alex Ghiculescu*, *Rafał Brize*
844
1222
 
845
- *Darwin Wu*
1223
+ * Allow overriding SQLite defaults from `database.yml`.
846
1224
 
847
- * Configuration item `config.filter_parameters` could also filter out
848
- sensitive values of database columns when calling `#inspect`.
849
- We also added `ActiveRecord::Base::filter_attributes`/`=` in order to
850
- specify sensitive attributes to specific model.
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.
851
1228
 
852
- ```
853
- Rails.application.config.filter_parameters += [:credit_card_number, /phone/]
854
- Account.last.inspect # => #<Account id: 123, name: "DHH", credit_card_number: [FILTERED], telephone_number: [FILTERED] ...>
855
- SecureAccount.filter_attributes += [:name]
856
- SecureAccount.last.inspect # => #<SecureAccount id: 42, name: [FILTERED], credit_card_number: [FILTERED] ...>
1229
+ ```yaml
1230
+ database: storage/development.sqlite3
1231
+ timeout: 5000
1232
+ pragmas:
1233
+ journal_mode: off
1234
+ temp_store: memory
857
1235
  ```
858
1236
 
859
- *Zhang Kang*, *Yoshiyuki Kinjo*
1237
+ *Stephen Margheim*
860
1238
 
861
- * Deprecate `column_name_length`, `table_name_length`, `columns_per_table`,
862
- `indexes_per_table`, `columns_per_multicolumn_index`, `sql_query_length`,
863
- and `joins_per_query` methods in `DatabaseLimits`.
1239
+ * Remove warning message when running SQLite in production, but leave it unconfigured.
864
1240
 
865
- *Ryuta Kamizono*
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.
866
1245
 
867
- * `ActiveRecord::Base.configurations` now returns an object.
1246
+ *Jacopo Beschi*, *Jean Boussier*
868
1247
 
869
- `ActiveRecord::Base.configurations` used to return a hash, but this
870
- is an inflexible data model. In order to improve multiple-database
871
- handling in Rails, we've changed this to return an object. Some methods
872
- are provided to make the object behave hash-like in order to ease the
873
- transition process. Since most applications don't manipulate the hash
874
- we've decided to add backwards-compatible functionality that will throw
875
- a deprecation warning if used, however calling `ActiveRecord::Base.configurations`
876
- will use the new version internally and externally.
1248
+ * Add support for generated columns to the SQLite3 adapter.
877
1249
 
878
- For example, the following `database.yml`:
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.
879
1252
 
880
- ```
881
- development:
882
- adapter: sqlite3
883
- database: db/development.sqlite3
1253
+ ```ruby
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
1258
+ end
884
1259
  ```
885
1260
 
886
- Used to become a hash:
1261
+ *Stephen Margheim*
887
1262
 
888
- ```
889
- { "development" => { "adapter" => "sqlite3", "database" => "db/development.sqlite3" } }
890
- ```
1263
+ * TrilogyAdapter: ignore `host` if `socket` parameter is set.
891
1264
 
892
- Is now converted into the following object:
1265
+ This allows to configure a connection on a UNIX socket via `DATABASE_URL`:
893
1266
 
894
1267
  ```
895
- #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
896
- #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
897
- @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
898
- ]
1268
+ DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
899
1269
  ```
900
1270
 
901
- Iterating over the database configurations has also changed. Instead of
902
- calling hash methods on the `configurations` hash directly, a new method `configs_for` has
903
- been provided that allows you to select the correct configuration. `env_name` and
904
- `spec_name` arguments are optional. For example, these return an array of
905
- database config objects for the requested environment and a single database config object
906
- will be returned for the requested environment and specification name respectively.
1271
+ *Jean Boussier*
907
1272
 
908
- ```
909
- ActiveRecord::Base.configurations.configs_for(env_name: "development")
910
- ActiveRecord::Base.configurations.configs_for(env_name: "development", spec_name: "primary")
911
- ```
1273
+ * Make `assert_queries_count`, `assert_no_queries`, `assert_queries_match`, and
1274
+ `assert_no_queries_match` assertions public.
912
1275
 
913
- *Eileen M. Uchitelle*, *Aaron Patterson*
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.
914
1279
 
915
- * Add database configuration to disable advisory locks.
1280
+ ```ruby
1281
+ class ArticleTest < ActiveSupport::TestCase
1282
+ test "queries are made" do
1283
+ assert_queries_count(1) { Article.first }
1284
+ end
916
1285
 
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
1290
+ end
1291
+ end
917
1292
  ```
918
- production:
919
- adapter: postgresql
920
- advisory_locks: false
921
- ```
922
-
923
- *Guo Xiang*
924
1293
 
925
- * SQLite3 adapter `alter_table` method restores foreign keys.
1294
+ *Petrik de Heus*, *fatkodima*
926
1295
 
927
- *Yasuo Honda*
1296
+ * Fix `has_secure_token` calls the setter method on initialize.
928
1297
 
929
- * Allow `:to_table` option to `invert_remove_foreign_key`.
1298
+ *Abeid Ahmed*
930
1299
 
931
- Example:
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.
932
1303
 
933
- remove_foreign_key :accounts, to_table: :owners
1304
+ ```ruby
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
1308
+ ```
934
1309
 
935
- *Nikolay Epifanov*, *Rich Chen*
1310
+ *Jean Boussier*, *Kevin McPhillips*
936
1311
 
937
- * Add environment & load_config dependency to `bin/rake db:seed` to enable
938
- seed load in environments without Rails and custom DB configuration
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).
939
1315
 
940
- *Tobias Bielohlawek*
1316
+ *Kevin McPhillips*
941
1317
 
942
- * Fix default value for mysql time types with specified precision.
1318
+ * `DatabaseConfigurations#configs_for` accepts a symbol in the `name` parameter.
943
1319
 
944
- *Nikolay Kondratyev*
1320
+ *Andrew Novoselac*
945
1321
 
946
- * Fix `touch` option to behave consistently with `Persistence#touch` method.
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).
947
1325
 
948
- *Ryuta Kamizono*
1326
+ *João Alves*
949
1327
 
950
- * Migrations raise when duplicate column definition.
1328
+ * Make the output of `ActiveRecord::Core#inspect` configurable.
951
1329
 
952
- Fixes #33024.
1330
+ By default, calling `inspect` on a record will yield a formatted string including just the `id`.
953
1331
 
954
- *Federico Martinez*
1332
+ ```ruby
1333
+ Post.first.inspect #=> "#<Post id: 1>"
1334
+ ```
955
1335
 
956
- * Bump minimum SQLite version to 3.8
1336
+ The attributes to be included in the output of `inspect` can be configured with
1337
+ `ActiveRecord::Core#attributes_for_inspect`.
957
1338
 
958
- *Yasuo Honda*
1339
+ ```ruby
1340
+ Post.attributes_for_inspect = [:id, :title]
1341
+ Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
1342
+ ```
959
1343
 
960
- * Fix parent record should not get saved with duplicate children records.
1344
+ With `attributes_for_inspect` set to `:all`, `inspect` will list all the record's attributes.
961
1345
 
962
- Fixes #32940.
1346
+ ```ruby
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">"
1349
+ ```
963
1350
 
964
- *Santosh Wadghule*
1351
+ In `development` and `test` mode, `attributes_for_inspect` will be set to `:all` by default.
965
1352
 
966
- * Fix logic on disabling commit callbacks so they are not called unexpectedly when errors occur.
1353
+ You can also call `full_inspect` to get an inspection with all the attributes.
967
1354
 
968
- *Brian Durand*
1355
+ The attributes in `attribute_for_inspect` will also be used for `pretty_print`.
969
1356
 
970
- * Ensure `Associations::CollectionAssociation#size` and `Associations::CollectionAssociation#empty?`
971
- use loaded association ids if present.
1357
+ *Andrew Novoselac*
972
1358
 
973
- *Graham Turner*
1359
+ * Don't mark attributes as changed when reassigned to `Float::INFINITY` or
1360
+ `-Float::INFINITY`.
974
1361
 
975
- * Add support to preload associations of polymorphic associations when not all the records have the requested associations.
1362
+ *Maicol Bentancor*
976
1363
 
977
- *Dana Sherson*
1364
+ * Support the `RETURNING` clause for MariaDB.
978
1365
 
979
- * Add `touch_all` method to `ActiveRecord::Relation`.
1366
+ *fatkodima*, *Nikolay Kondratyev*
980
1367
 
981
- Example:
1368
+ * The SQLite3 adapter now implements the `supports_deferrable_constraints?` contract.
982
1369
 
983
- Person.where(name: "David").touch_all(time: Time.new(2020, 5, 16, 0, 0, 0))
1370
+ Allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options.
984
1371
 
985
- *fatkodima*, *duggiefresh*
1372
+ ```ruby
1373
+ add_reference :person, :alias, foreign_key: { deferrable: :deferred }
1374
+ add_reference :alias, :person, foreign_key: { deferrable: :deferred }
1375
+ ```
986
1376
 
987
- * Add `ActiveRecord::Base.base_class?` predicate.
1377
+ *Stephen Margheim*
988
1378
 
989
- *Bogdan Gusiev*
1379
+ * Add the `set_constraints` helper to PostgreSQL connections.
990
1380
 
991
- * Add custom prefix/suffix options to `ActiveRecord::Store.store_accessor`.
1381
+ ```ruby
1382
+ Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
1383
+
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!
1390
+ end
1391
+ ```
992
1392
 
993
- *Tan Huynh*, *Yukio Mizuta*
1393
+ *Cody Cutrer*
994
1394
 
995
- * Rails 6 requires Ruby 2.5.0 or newer.
1395
+ * Include `ActiveModel::API` in `ActiveRecord::Base`.
996
1396
 
997
- *Jeremy Daer*, *Kasper Timm Hansen*
1397
+ *Sean Doyle*
998
1398
 
999
- * Deprecate `update_attributes`/`!` in favor of `update`/`!`.
1399
+ * Ensure `#signed_id` outputs `url_safe` strings.
1000
1400
 
1001
- *Eddie Lebow*
1401
+ *Jason Meller*
1002
1402
 
1003
- * Add `ActiveRecord::Base.create_or_find_by`/`!` to deal with the SELECT/INSERT race condition in
1004
- `ActiveRecord::Base.find_or_create_by`/`!` by leaning on unique constraints in the database.
1403
+ * Add `nulls_last` and working `desc.nulls_first` for MySQL.
1005
1404
 
1006
- *DHH*
1405
+ *Tristan Fellows*
1007
1406
 
1008
- * Add `Relation#pick` as short-hand for single-value plucks.
1407
+ * Allow for more complex hash arguments for `order` which mimics `where` in `ActiveRecord::Relation`.
1009
1408
 
1010
- *DHH*
1409
+ ```ruby
1410
+ Topic.includes(:posts).order(posts: { created_at: :desc })
1411
+ ```
1011
1412
 
1413
+ *Myles Boone*
1012
1414
 
1013
- Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-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.