activerecord 7.0.8.7 → 7.2.2.1

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