activerecord 6.1.7 → 7.1.5

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 (311) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2030 -1020
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  5. data/lib/active_record/aggregations.rb +17 -14
  6. data/lib/active_record/association_relation.rb +1 -11
  7. data/lib/active_record/associations/association.rb +51 -19
  8. data/lib/active_record/associations/association_scope.rb +17 -12
  9. data/lib/active_record/associations/belongs_to_association.rb +28 -9
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +11 -5
  12. data/lib/active_record/associations/builder/belongs_to.rb +40 -14
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  15. data/lib/active_record/associations/builder/has_many.rb +3 -2
  16. data/lib/active_record/associations/builder/has_one.rb +2 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  18. data/lib/active_record/associations/collection_association.rb +39 -35
  19. data/lib/active_record/associations/collection_proxy.rb +30 -15
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  21. data/lib/active_record/associations/foreign_association.rb +10 -3
  22. data/lib/active_record/associations/has_many_association.rb +28 -18
  23. data/lib/active_record/associations/has_many_through_association.rb +12 -7
  24. data/lib/active_record/associations/has_one_association.rb +20 -10
  25. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  26. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  27. data/lib/active_record/associations/join_dependency.rb +28 -20
  28. data/lib/active_record/associations/preloader/association.rb +210 -52
  29. data/lib/active_record/associations/preloader/batch.rb +48 -0
  30. data/lib/active_record/associations/preloader/branch.rb +147 -0
  31. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  32. data/lib/active_record/associations/preloader.rb +50 -121
  33. data/lib/active_record/associations/singular_association.rb +9 -3
  34. data/lib/active_record/associations/through_association.rb +25 -14
  35. data/lib/active_record/associations.rb +446 -306
  36. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  37. data/lib/active_record/attribute_assignment.rb +1 -3
  38. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  39. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  40. data/lib/active_record/attribute_methods/primary_key.rb +78 -26
  41. data/lib/active_record/attribute_methods/query.rb +31 -19
  42. data/lib/active_record/attribute_methods/read.rb +27 -12
  43. data/lib/active_record/attribute_methods/serialization.rb +194 -37
  44. data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
  45. data/lib/active_record/attribute_methods/write.rb +12 -15
  46. data/lib/active_record/attribute_methods.rb +161 -40
  47. data/lib/active_record/attributes.rb +27 -38
  48. data/lib/active_record/autosave_association.rb +65 -31
  49. data/lib/active_record/base.rb +25 -2
  50. data/lib/active_record/callbacks.rb +18 -34
  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 -46
  54. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +113 -597
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -27
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +367 -141
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -150
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +317 -164
  70. data/lib/active_record/connection_adapters/column.rb +13 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +39 -14
  78. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +112 -55
  80. data/lib/active_record/connection_adapters/pool_config.rb +20 -11
  81. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  89. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +397 -75
  101. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  102. data/lib/active_record/connection_adapters/postgresql_adapter.rb +508 -246
  103. data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
  104. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  105. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
  106. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
  107. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  108. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
  109. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +296 -104
  110. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  111. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  112. data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
  113. data/lib/active_record/connection_adapters.rb +9 -6
  114. data/lib/active_record/connection_handling.rb +108 -137
  115. data/lib/active_record/core.rb +242 -233
  116. data/lib/active_record/counter_cache.rb +52 -27
  117. data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -2
  118. data/lib/active_record/database_configurations/database_config.rb +21 -12
  119. data/lib/active_record/database_configurations/hash_config.rb +88 -16
  120. data/lib/active_record/database_configurations/url_config.rb +18 -12
  121. data/lib/active_record/database_configurations.rb +95 -59
  122. data/lib/active_record/delegated_type.rb +66 -20
  123. data/lib/active_record/deprecator.rb +7 -0
  124. data/lib/active_record/destroy_association_async_job.rb +4 -2
  125. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  126. data/lib/active_record/dynamic_matchers.rb +1 -1
  127. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  128. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  129. data/lib/active_record/encryption/cipher.rb +53 -0
  130. data/lib/active_record/encryption/config.rb +68 -0
  131. data/lib/active_record/encryption/configurable.rb +60 -0
  132. data/lib/active_record/encryption/context.rb +42 -0
  133. data/lib/active_record/encryption/contexts.rb +76 -0
  134. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  135. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  136. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  137. data/lib/active_record/encryption/encrypted_attribute_type.rb +155 -0
  138. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  139. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  140. data/lib/active_record/encryption/encryptor.rb +155 -0
  141. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  142. data/lib/active_record/encryption/errors.rb +15 -0
  143. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  144. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  145. data/lib/active_record/encryption/key.rb +28 -0
  146. data/lib/active_record/encryption/key_generator.rb +53 -0
  147. data/lib/active_record/encryption/key_provider.rb +46 -0
  148. data/lib/active_record/encryption/message.rb +33 -0
  149. data/lib/active_record/encryption/message_serializer.rb +92 -0
  150. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  151. data/lib/active_record/encryption/properties.rb +76 -0
  152. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  153. data/lib/active_record/encryption/scheme.rb +100 -0
  154. data/lib/active_record/encryption.rb +58 -0
  155. data/lib/active_record/enum.rb +154 -63
  156. data/lib/active_record/errors.rb +172 -15
  157. data/lib/active_record/explain.rb +23 -3
  158. data/lib/active_record/explain_registry.rb +11 -6
  159. data/lib/active_record/explain_subscriber.rb +1 -1
  160. data/lib/active_record/fixture_set/file.rb +15 -1
  161. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  162. data/lib/active_record/fixture_set/render_context.rb +2 -0
  163. data/lib/active_record/fixture_set/table_row.rb +70 -14
  164. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  165. data/lib/active_record/fixtures.rb +147 -86
  166. data/lib/active_record/future_result.rb +174 -0
  167. data/lib/active_record/gem_version.rb +3 -3
  168. data/lib/active_record/inheritance.rb +81 -29
  169. data/lib/active_record/insert_all.rb +135 -22
  170. data/lib/active_record/integration.rb +11 -10
  171. data/lib/active_record/internal_metadata.rb +119 -33
  172. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  173. data/lib/active_record/locking/optimistic.rb +37 -22
  174. data/lib/active_record/locking/pessimistic.rb +15 -6
  175. data/lib/active_record/log_subscriber.rb +52 -19
  176. data/lib/active_record/marshalling.rb +59 -0
  177. data/lib/active_record/message_pack.rb +124 -0
  178. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  179. data/lib/active_record/middleware/database_selector.rb +23 -13
  180. data/lib/active_record/middleware/shard_selector.rb +62 -0
  181. data/lib/active_record/migration/command_recorder.rb +112 -14
  182. data/lib/active_record/migration/compatibility.rb +233 -46
  183. data/lib/active_record/migration/default_strategy.rb +23 -0
  184. data/lib/active_record/migration/execution_strategy.rb +19 -0
  185. data/lib/active_record/migration/join_table.rb +1 -1
  186. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  187. data/lib/active_record/migration.rb +361 -173
  188. data/lib/active_record/model_schema.rb +125 -101
  189. data/lib/active_record/nested_attributes.rb +50 -20
  190. data/lib/active_record/no_touching.rb +3 -3
  191. data/lib/active_record/normalization.rb +167 -0
  192. data/lib/active_record/persistence.rb +409 -88
  193. data/lib/active_record/promise.rb +84 -0
  194. data/lib/active_record/query_cache.rb +4 -22
  195. data/lib/active_record/query_logs.rb +174 -0
  196. data/lib/active_record/query_logs_formatter.rb +41 -0
  197. data/lib/active_record/querying.rb +29 -6
  198. data/lib/active_record/railtie.rb +220 -44
  199. data/lib/active_record/railties/controller_runtime.rb +15 -10
  200. data/lib/active_record/railties/databases.rake +188 -252
  201. data/lib/active_record/railties/job_runtime.rb +23 -0
  202. data/lib/active_record/readonly_attributes.rb +41 -3
  203. data/lib/active_record/reflection.rb +248 -81
  204. data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
  205. data/lib/active_record/relation/batches.rb +192 -63
  206. data/lib/active_record/relation/calculations.rb +246 -90
  207. data/lib/active_record/relation/delegation.rb +28 -14
  208. data/lib/active_record/relation/finder_methods.rb +108 -51
  209. data/lib/active_record/relation/merger.rb +22 -13
  210. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  211. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  212. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  213. data/lib/active_record/relation/predicate_builder.rb +27 -20
  214. data/lib/active_record/relation/query_attribute.rb +30 -12
  215. data/lib/active_record/relation/query_methods.rb +670 -129
  216. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  217. data/lib/active_record/relation/spawn_methods.rb +20 -3
  218. data/lib/active_record/relation/where_clause.rb +10 -19
  219. data/lib/active_record/relation.rb +287 -120
  220. data/lib/active_record/result.rb +37 -11
  221. data/lib/active_record/runtime_registry.rb +32 -13
  222. data/lib/active_record/sanitization.rb +65 -20
  223. data/lib/active_record/schema.rb +36 -22
  224. data/lib/active_record/schema_dumper.rb +73 -24
  225. data/lib/active_record/schema_migration.rb +68 -33
  226. data/lib/active_record/scoping/default.rb +72 -15
  227. data/lib/active_record/scoping/named.rb +5 -13
  228. data/lib/active_record/scoping.rb +65 -34
  229. data/lib/active_record/secure_password.rb +60 -0
  230. data/lib/active_record/secure_token.rb +21 -3
  231. data/lib/active_record/serialization.rb +6 -1
  232. data/lib/active_record/signed_id.rb +10 -8
  233. data/lib/active_record/store.rb +10 -10
  234. data/lib/active_record/suppressor.rb +13 -15
  235. data/lib/active_record/table_metadata.rb +16 -3
  236. data/lib/active_record/tasks/database_tasks.rb +251 -140
  237. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  238. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  239. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  240. data/lib/active_record/test_databases.rb +1 -1
  241. data/lib/active_record/test_fixtures.rb +117 -96
  242. data/lib/active_record/timestamp.rb +32 -19
  243. data/lib/active_record/token_for.rb +113 -0
  244. data/lib/active_record/touch_later.rb +11 -6
  245. data/lib/active_record/transactions.rb +48 -27
  246. data/lib/active_record/translation.rb +3 -3
  247. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  248. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  249. data/lib/active_record/type/internal/timezone.rb +7 -2
  250. data/lib/active_record/type/serialized.rb +9 -5
  251. data/lib/active_record/type/time.rb +4 -0
  252. data/lib/active_record/type/type_map.rb +17 -20
  253. data/lib/active_record/type.rb +1 -2
  254. data/lib/active_record/validations/absence.rb +1 -1
  255. data/lib/active_record/validations/associated.rb +4 -4
  256. data/lib/active_record/validations/numericality.rb +5 -4
  257. data/lib/active_record/validations/presence.rb +5 -28
  258. data/lib/active_record/validations/uniqueness.rb +51 -6
  259. data/lib/active_record/validations.rb +8 -4
  260. data/lib/active_record/version.rb +1 -1
  261. data/lib/active_record.rb +335 -32
  262. data/lib/arel/attributes/attribute.rb +0 -8
  263. data/lib/arel/crud.rb +28 -22
  264. data/lib/arel/delete_manager.rb +18 -4
  265. data/lib/arel/errors.rb +10 -0
  266. data/lib/arel/factory_methods.rb +4 -0
  267. data/lib/arel/filter_predications.rb +9 -0
  268. data/lib/arel/insert_manager.rb +2 -3
  269. data/lib/arel/nodes/and.rb +4 -0
  270. data/lib/arel/nodes/binary.rb +6 -1
  271. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  272. data/lib/arel/nodes/casted.rb +1 -1
  273. data/lib/arel/nodes/cte.rb +36 -0
  274. data/lib/arel/nodes/delete_statement.rb +12 -13
  275. data/lib/arel/nodes/filter.rb +10 -0
  276. data/lib/arel/nodes/fragments.rb +35 -0
  277. data/lib/arel/nodes/function.rb +1 -0
  278. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  279. data/lib/arel/nodes/insert_statement.rb +2 -2
  280. data/lib/arel/nodes/leading_join.rb +8 -0
  281. data/lib/arel/nodes/node.rb +111 -2
  282. data/lib/arel/nodes/select_core.rb +2 -2
  283. data/lib/arel/nodes/select_statement.rb +2 -2
  284. data/lib/arel/nodes/sql_literal.rb +6 -0
  285. data/lib/arel/nodes/table_alias.rb +4 -0
  286. data/lib/arel/nodes/update_statement.rb +8 -3
  287. data/lib/arel/nodes.rb +5 -0
  288. data/lib/arel/predications.rb +13 -3
  289. data/lib/arel/select_manager.rb +10 -4
  290. data/lib/arel/table.rb +9 -6
  291. data/lib/arel/tree_manager.rb +5 -13
  292. data/lib/arel/update_manager.rb +18 -4
  293. data/lib/arel/visitors/dot.rb +80 -90
  294. data/lib/arel/visitors/mysql.rb +16 -3
  295. data/lib/arel/visitors/postgresql.rb +0 -10
  296. data/lib/arel/visitors/to_sql.rb +141 -20
  297. data/lib/arel/visitors/visitor.rb +2 -2
  298. data/lib/arel.rb +18 -3
  299. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  300. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  301. data/lib/rails/generators/active_record/migration.rb +3 -1
  302. data/lib/rails/generators/active_record/model/USAGE +113 -0
  303. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  304. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  305. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  306. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  307. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  308. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  309. metadata +96 -16
  310. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  311. data/lib/active_record/null_relation.rb +0 -67
@@ -12,7 +12,7 @@ require "active_record/attributes"
12
12
  require "active_record/type_caster"
13
13
  require "active_record/database_configurations"
14
14
 
15
- module ActiveRecord #:nodoc:
15
+ module ActiveRecord # :nodoc:
16
16
  # = Active Record
17
17
  #
18
18
  # Active Record objects don't specify their attributes directly, but rather infer them from
@@ -137,6 +137,23 @@ module ActiveRecord #:nodoc:
137
137
  # anonymous = User.new(name: "")
138
138
  # anonymous.name? # => false
139
139
  #
140
+ # Query methods will also respect any overrides of default accessors:
141
+ #
142
+ # class User
143
+ # # Has admin boolean column
144
+ # def admin
145
+ # false
146
+ # end
147
+ # end
148
+ #
149
+ # user.update(admin: true)
150
+ #
151
+ # user.read_attribute(:admin) # => true, gets the column value
152
+ # user[:admin] # => true, also gets the column value
153
+ #
154
+ # user.admin # => false, due to the getter override
155
+ # user.admin? # => false, due to the getter override
156
+ #
140
157
  # == Accessing attributes before they have been typecasted
141
158
  #
142
159
  # Sometimes you want to be able to read the raw attribute data without having the column-determined
@@ -294,11 +311,12 @@ module ActiveRecord #:nodoc:
294
311
  include Attributes
295
312
  include Locking::Optimistic
296
313
  include Locking::Pessimistic
314
+ include Encryption::EncryptableRecord
297
315
  include AttributeMethods
298
316
  include Callbacks
299
317
  include Timestamp
300
318
  include Associations
301
- include ActiveModel::SecurePassword
319
+ include SecurePassword
302
320
  include AutosaveAssociation
303
321
  include NestedAttributes
304
322
  include Transactions
@@ -308,8 +326,13 @@ module ActiveRecord #:nodoc:
308
326
  include Serialization
309
327
  include Store
310
328
  include SecureToken
329
+ include TokenFor
311
330
  include SignedId
312
331
  include Suppressor
332
+ include Normalization
333
+ include Marshalling::Methods
334
+
335
+ self.param_delimiter = "_"
313
336
  end
314
337
 
315
338
  ActiveSupport.run_load_hooks(:active_record, Base)
@@ -84,7 +84,7 @@ module ActiveRecord
84
84
  # == Types of callbacks
85
85
  #
86
86
  # There are three types of callbacks accepted by the callback macros: method references (symbol), callback objects,
87
- # inline methods (using a proc). Method references and callback objects are the recommended approaches,
87
+ # inline methods (using a proc). \Method references and callback objects are the recommended approaches,
88
88
  # inline methods using a proc are sometimes appropriate (such as for creating mix-ins).
89
89
  #
90
90
  # The method reference callbacks work by specifying a protected or private method available in the object, like this:
@@ -173,7 +173,7 @@ module ActiveRecord
173
173
  #
174
174
  # If a <tt>before_*</tt> callback throws +:abort+, all the later callbacks and
175
175
  # the associated action are cancelled.
176
- # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
176
+ # \Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
177
177
  # methods on the model, which are called last.
178
178
  #
179
179
  # == Ordering callbacks
@@ -224,42 +224,26 @@ module ActiveRecord
224
224
  # after_save :do_something_else
225
225
  #
226
226
  # private
227
+ # def log_children
228
+ # # Child processing
229
+ # end
227
230
  #
228
- # def log_children
229
- # # Child processing
230
- # end
231
- #
232
- # def do_something_else
233
- # # Something else
234
- # end
231
+ # def do_something_else
232
+ # # Something else
233
+ # end
235
234
  # end
236
235
  #
237
236
  # In this case the +log_children+ is executed before +do_something_else+.
238
- # The same applies to all non-transactional callbacks.
237
+ # This applies to all non-transactional callbacks, and to +before_commit+.
239
238
  #
240
- # As seen below, in case there are multiple transactional callbacks the order
241
- # is reversed.
239
+ # For transactional +after_+ callbacks (+after_commit+, +after_rollback+, etc), the order
240
+ # can be set via configuration.
242
241
  #
243
- # For example:
244
- #
245
- # class Topic < ActiveRecord::Base
246
- # has_many :children
247
- #
248
- # after_commit :log_children
249
- # after_commit :do_something_else
250
- #
251
- # private
252
- #
253
- # def log_children
254
- # # Child processing
255
- # end
256
- #
257
- # def do_something_else
258
- # # Something else
259
- # end
260
- # end
242
+ # config.active_record.run_after_transaction_callbacks_in_order_defined = false
261
243
  #
262
- # In this case the +do_something_else+ is executed before +log_children+.
244
+ # When set to +true+ (the default from \Rails 7.1), callbacks are executed in the order they
245
+ # are defined, just like the example above. When set to +false+, the order is reversed, so
246
+ # +do_something_else+ is executed before +log_children+.
263
247
  #
264
248
  # == \Transactions
265
249
  #
@@ -432,7 +416,7 @@ module ActiveRecord
432
416
  define_model_callbacks :save, :create, :update, :destroy
433
417
  end
434
418
 
435
- def destroy #:nodoc:
419
+ def destroy # :nodoc:
436
420
  @_destroy_callback_already_called ||= false
437
421
  return if @_destroy_callback_already_called
438
422
  @_destroy_callback_already_called = true
@@ -444,7 +428,7 @@ module ActiveRecord
444
428
  @_destroy_callback_already_called = false
445
429
  end
446
430
 
447
- def touch(*, **) #:nodoc:
431
+ def touch(*, **) # :nodoc:
448
432
  _run_touch_callbacks { super }
449
433
  end
450
434
 
@@ -462,7 +446,7 @@ module ActiveRecord
462
446
  end
463
447
 
464
448
  def _update_record
465
- _run_update_callbacks { super }
449
+ _run_update_callbacks { record_update_timestamps { super } }
466
450
  end
467
451
  end
468
452
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Coders # :nodoc:
5
+ class ColumnSerializer # :nodoc:
6
+ attr_reader :object_class
7
+ attr_reader :coder
8
+
9
+ def initialize(attr_name, coder, object_class = Object)
10
+ @attr_name = attr_name
11
+ @object_class = object_class
12
+ @coder = coder
13
+ check_arity_of_constructor
14
+ end
15
+
16
+ def init_with(coder) # :nodoc:
17
+ @attr_name = coder["attr_name"]
18
+ @object_class = coder["object_class"]
19
+ @coder = coder["coder"]
20
+ end
21
+
22
+ def dump(object)
23
+ return if object.nil?
24
+
25
+ assert_valid_value(object, action: "dump")
26
+ coder.dump(object)
27
+ end
28
+
29
+ def load(payload)
30
+ if payload.nil?
31
+ if @object_class != ::Object
32
+ return @object_class.new
33
+ end
34
+ return nil
35
+ end
36
+
37
+ object = coder.load(payload)
38
+
39
+ assert_valid_value(object, action: "load")
40
+ object ||= object_class.new if object_class != Object
41
+
42
+ object
43
+ end
44
+
45
+ # Public because it's called by Type::Serialized
46
+ def assert_valid_value(object, action:)
47
+ unless object.nil? || object_class === object
48
+ raise SerializationTypeMismatch,
49
+ "can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{object.class}. -- #{object.inspect}"
50
+ end
51
+ end
52
+
53
+ private
54
+ def check_arity_of_constructor
55
+ load(nil)
56
+ rescue ArgumentError
57
+ raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
58
+ end
59
+ end
60
+ end
61
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Coders # :nodoc:
5
- class JSON # :nodoc:
5
+ module JSON # :nodoc:
6
6
  def self.dump(obj)
7
7
  ActiveSupport::JSON.encode(obj)
8
8
  end
@@ -4,37 +4,83 @@ require "yaml"
4
4
 
5
5
  module ActiveRecord
6
6
  module Coders # :nodoc:
7
- class YAMLColumn # :nodoc:
8
- attr_accessor :object_class
9
-
10
- def initialize(attr_name, object_class = Object)
11
- @attr_name = attr_name
12
- @object_class = object_class
13
- check_arity_of_constructor
14
- end
7
+ class YAMLColumn < ColumnSerializer # :nodoc:
8
+ class SafeCoder
9
+ def initialize(permitted_classes: [], unsafe_load: nil)
10
+ @permitted_classes = permitted_classes
11
+ @unsafe_load = unsafe_load
12
+ end
15
13
 
16
- def dump(obj)
17
- return if obj.nil?
14
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("5.1")
15
+ def dump(object)
16
+ if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
17
+ ::YAML.dump(object)
18
+ else
19
+ ::YAML.safe_dump(
20
+ object,
21
+ permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
22
+ aliases: true,
23
+ )
24
+ end
25
+ end
26
+ else
27
+ def dump(object)
28
+ YAML.dump(object)
29
+ end
30
+ end
18
31
 
19
- assert_valid_value(obj, action: "dump")
20
- YAML.dump obj
32
+ if YAML.respond_to?(:unsafe_load)
33
+ def load(payload)
34
+ if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
35
+ YAML.unsafe_load(payload)
36
+ else
37
+ YAML.safe_load(
38
+ payload,
39
+ permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
40
+ aliases: true,
41
+ )
42
+ end
43
+ end
44
+ else
45
+ def load(payload)
46
+ if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
47
+ YAML.load(payload)
48
+ else
49
+ YAML.safe_load(
50
+ payload,
51
+ permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
52
+ aliases: true,
53
+ )
54
+ end
55
+ end
56
+ end
21
57
  end
22
58
 
23
- def load(yaml)
24
- return object_class.new if object_class != Object && yaml.nil?
25
- return yaml unless yaml.is_a?(String) && yaml.start_with?("---")
26
- obj = yaml_load(yaml)
27
-
28
- assert_valid_value(obj, action: "load")
29
- obj ||= object_class.new if object_class != Object
59
+ def initialize(attr_name, object_class = Object, permitted_classes: [], unsafe_load: nil)
60
+ super(
61
+ attr_name,
62
+ SafeCoder.new(permitted_classes: permitted_classes || [], unsafe_load: unsafe_load),
63
+ object_class,
64
+ )
65
+ check_arity_of_constructor
66
+ end
30
67
 
31
- obj
68
+ def init_with(coder) # :nodoc:
69
+ unless coder["coder"]
70
+ permitted_classes = coder["permitted_classes"] || []
71
+ unsafe_load = coder["unsafe_load"] || false
72
+ coder["coder"] = SafeCoder.new(permitted_classes: permitted_classes, unsafe_load: unsafe_load)
73
+ end
74
+ super(coder)
32
75
  end
33
76
 
34
- def assert_valid_value(obj, action:)
35
- unless obj.nil? || obj.is_a?(object_class)
36
- raise SerializationTypeMismatch,
37
- "can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
77
+ def coder
78
+ # This is to retain forward compatibility when loading records serialized with Marshal
79
+ # from a previous version of Rails.
80
+ @coder ||= begin
81
+ permitted_classes = defined?(@permitted_classes) ? @permitted_classes : []
82
+ unsafe_load = defined?(@unsafe_load) && @unsafe_load.nil?
83
+ SafeCoder.new(permitted_classes: permitted_classes, unsafe_load: unsafe_load)
38
84
  end
39
85
  end
40
86
 
@@ -44,28 +90,6 @@ module ActiveRecord
44
90
  rescue ArgumentError
45
91
  raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
46
92
  end
47
-
48
- if YAML.respond_to?(:unsafe_load)
49
- def yaml_load(payload)
50
- if ActiveRecord::Base.use_yaml_unsafe_load
51
- YAML.unsafe_load(payload)
52
- elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
53
- YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
54
- else
55
- YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
56
- end
57
- end
58
- else
59
- def yaml_load(payload)
60
- if ActiveRecord::Base.use_yaml_unsafe_load
61
- YAML.load(payload)
62
- elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
63
- YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
64
- else
65
- YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
66
- end
67
- end
68
- end
69
93
  end
70
94
  end
71
95
  end