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