activerecord 6.1.7 → 7.1.0

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 (307) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1516 -1019
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +17 -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 +50 -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 +35 -31
  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.rb +26 -16
  27. data/lib/active_record/associations/preloader/association.rb +207 -52
  28. data/lib/active_record/associations/preloader/batch.rb +48 -0
  29. data/lib/active_record/associations/preloader/branch.rb +147 -0
  30. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  31. data/lib/active_record/associations/preloader.rb +50 -121
  32. data/lib/active_record/associations/singular_association.rb +9 -3
  33. data/lib/active_record/associations/through_association.rb +25 -14
  34. data/lib/active_record/associations.rb +423 -289
  35. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  36. data/lib/active_record/attribute_assignment.rb +1 -3
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  38. data/lib/active_record/attribute_methods/dirty.rb +61 -14
  39. data/lib/active_record/attribute_methods/primary_key.rb +78 -26
  40. data/lib/active_record/attribute_methods/query.rb +31 -19
  41. data/lib/active_record/attribute_methods/read.rb +25 -10
  42. data/lib/active_record/attribute_methods/serialization.rb +194 -37
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  44. data/lib/active_record/attribute_methods/write.rb +10 -13
  45. data/lib/active_record/attribute_methods.rb +121 -40
  46. data/lib/active_record/attributes.rb +27 -38
  47. data/lib/active_record/autosave_association.rb +61 -30
  48. data/lib/active_record/base.rb +25 -2
  49. data/lib/active_record/callbacks.rb +18 -34
  50. data/lib/active_record/coders/column_serializer.rb +61 -0
  51. data/lib/active_record/coders/json.rb +1 -1
  52. data/lib/active_record/coders/yaml_column.rb +70 -46
  53. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
  54. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -51
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -136
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +622 -149
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
  69. data/lib/active_record/connection_adapters/column.rb +13 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
  72. data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  76. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
  77. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
  78. data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
  79. data/lib/active_record/connection_adapters/pool_config.rb +20 -11
  80. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +18 -1
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -52
  83. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  87. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  91. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +381 -69
  98. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  99. data/lib/active_record/connection_adapters/postgresql_adapter.rb +492 -230
  100. data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
  101. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  102. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +65 -53
  103. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
  104. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  105. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
  107. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  108. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
  109. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  110. data/lib/active_record/connection_adapters.rb +9 -6
  111. data/lib/active_record/connection_handling.rb +107 -136
  112. data/lib/active_record/core.rb +194 -224
  113. data/lib/active_record/counter_cache.rb +46 -25
  114. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  115. data/lib/active_record/database_configurations/database_config.rb +21 -12
  116. data/lib/active_record/database_configurations/hash_config.rb +84 -16
  117. data/lib/active_record/database_configurations/url_config.rb +18 -12
  118. data/lib/active_record/database_configurations.rb +95 -59
  119. data/lib/active_record/delegated_type.rb +61 -15
  120. data/lib/active_record/deprecator.rb +7 -0
  121. data/lib/active_record/destroy_association_async_job.rb +3 -1
  122. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  123. data/lib/active_record/dynamic_matchers.rb +1 -1
  124. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  125. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  126. data/lib/active_record/encryption/cipher.rb +53 -0
  127. data/lib/active_record/encryption/config.rb +68 -0
  128. data/lib/active_record/encryption/configurable.rb +60 -0
  129. data/lib/active_record/encryption/context.rb +42 -0
  130. data/lib/active_record/encryption/contexts.rb +76 -0
  131. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  132. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  133. data/lib/active_record/encryption/encryptable_record.rb +224 -0
  134. data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
  135. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  136. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  137. data/lib/active_record/encryption/encryptor.rb +155 -0
  138. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  139. data/lib/active_record/encryption/errors.rb +15 -0
  140. data/lib/active_record/encryption/extended_deterministic_queries.rb +172 -0
  141. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  142. data/lib/active_record/encryption/key.rb +28 -0
  143. data/lib/active_record/encryption/key_generator.rb +53 -0
  144. data/lib/active_record/encryption/key_provider.rb +46 -0
  145. data/lib/active_record/encryption/message.rb +33 -0
  146. data/lib/active_record/encryption/message_serializer.rb +92 -0
  147. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  148. data/lib/active_record/encryption/properties.rb +76 -0
  149. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  150. data/lib/active_record/encryption/scheme.rb +96 -0
  151. data/lib/active_record/encryption.rb +56 -0
  152. data/lib/active_record/enum.rb +156 -62
  153. data/lib/active_record/errors.rb +171 -15
  154. data/lib/active_record/explain.rb +23 -3
  155. data/lib/active_record/explain_registry.rb +11 -6
  156. data/lib/active_record/explain_subscriber.rb +1 -1
  157. data/lib/active_record/fixture_set/file.rb +15 -1
  158. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  159. data/lib/active_record/fixture_set/render_context.rb +2 -0
  160. data/lib/active_record/fixture_set/table_row.rb +70 -14
  161. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  162. data/lib/active_record/fixtures.rb +131 -86
  163. data/lib/active_record/future_result.rb +164 -0
  164. data/lib/active_record/gem_version.rb +3 -3
  165. data/lib/active_record/inheritance.rb +81 -29
  166. data/lib/active_record/insert_all.rb +133 -20
  167. data/lib/active_record/integration.rb +11 -10
  168. data/lib/active_record/internal_metadata.rb +117 -33
  169. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  170. data/lib/active_record/locking/optimistic.rb +36 -21
  171. data/lib/active_record/locking/pessimistic.rb +15 -6
  172. data/lib/active_record/log_subscriber.rb +52 -19
  173. data/lib/active_record/marshalling.rb +56 -0
  174. data/lib/active_record/message_pack.rb +124 -0
  175. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  176. data/lib/active_record/middleware/database_selector.rb +23 -13
  177. data/lib/active_record/middleware/shard_selector.rb +62 -0
  178. data/lib/active_record/migration/command_recorder.rb +108 -13
  179. data/lib/active_record/migration/compatibility.rb +221 -48
  180. data/lib/active_record/migration/default_strategy.rb +23 -0
  181. data/lib/active_record/migration/execution_strategy.rb +19 -0
  182. data/lib/active_record/migration/join_table.rb +1 -1
  183. data/lib/active_record/migration.rb +355 -171
  184. data/lib/active_record/model_schema.rb +116 -97
  185. data/lib/active_record/nested_attributes.rb +36 -15
  186. data/lib/active_record/no_touching.rb +3 -3
  187. data/lib/active_record/normalization.rb +159 -0
  188. data/lib/active_record/persistence.rb +405 -85
  189. data/lib/active_record/promise.rb +84 -0
  190. data/lib/active_record/query_cache.rb +3 -21
  191. data/lib/active_record/query_logs.rb +174 -0
  192. data/lib/active_record/query_logs_formatter.rb +41 -0
  193. data/lib/active_record/querying.rb +29 -6
  194. data/lib/active_record/railtie.rb +219 -43
  195. data/lib/active_record/railties/controller_runtime.rb +13 -9
  196. data/lib/active_record/railties/databases.rake +185 -249
  197. data/lib/active_record/railties/job_runtime.rb +23 -0
  198. data/lib/active_record/readonly_attributes.rb +41 -3
  199. data/lib/active_record/reflection.rb +229 -80
  200. data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
  201. data/lib/active_record/relation/batches.rb +192 -63
  202. data/lib/active_record/relation/calculations.rb +211 -90
  203. data/lib/active_record/relation/delegation.rb +27 -13
  204. data/lib/active_record/relation/finder_methods.rb +108 -51
  205. data/lib/active_record/relation/merger.rb +22 -13
  206. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  207. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  208. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  209. data/lib/active_record/relation/predicate_builder.rb +27 -20
  210. data/lib/active_record/relation/query_attribute.rb +30 -12
  211. data/lib/active_record/relation/query_methods.rb +654 -127
  212. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  213. data/lib/active_record/relation/spawn_methods.rb +20 -3
  214. data/lib/active_record/relation/where_clause.rb +10 -19
  215. data/lib/active_record/relation.rb +262 -120
  216. data/lib/active_record/result.rb +37 -11
  217. data/lib/active_record/runtime_registry.rb +18 -13
  218. data/lib/active_record/sanitization.rb +65 -20
  219. data/lib/active_record/schema.rb +36 -22
  220. data/lib/active_record/schema_dumper.rb +73 -24
  221. data/lib/active_record/schema_migration.rb +68 -33
  222. data/lib/active_record/scoping/default.rb +72 -15
  223. data/lib/active_record/scoping/named.rb +5 -13
  224. data/lib/active_record/scoping.rb +65 -34
  225. data/lib/active_record/secure_password.rb +60 -0
  226. data/lib/active_record/secure_token.rb +21 -3
  227. data/lib/active_record/serialization.rb +6 -1
  228. data/lib/active_record/signed_id.rb +10 -8
  229. data/lib/active_record/store.rb +10 -10
  230. data/lib/active_record/suppressor.rb +13 -15
  231. data/lib/active_record/table_metadata.rb +16 -3
  232. data/lib/active_record/tasks/database_tasks.rb +225 -136
  233. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  234. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  235. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  236. data/lib/active_record/test_databases.rb +1 -1
  237. data/lib/active_record/test_fixtures.rb +116 -96
  238. data/lib/active_record/timestamp.rb +28 -17
  239. data/lib/active_record/token_for.rb +113 -0
  240. data/lib/active_record/touch_later.rb +11 -6
  241. data/lib/active_record/transactions.rb +48 -27
  242. data/lib/active_record/translation.rb +3 -3
  243. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  244. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  245. data/lib/active_record/type/internal/timezone.rb +7 -2
  246. data/lib/active_record/type/serialized.rb +9 -5
  247. data/lib/active_record/type/time.rb +4 -0
  248. data/lib/active_record/type/type_map.rb +17 -20
  249. data/lib/active_record/type.rb +1 -2
  250. data/lib/active_record/validations/absence.rb +1 -1
  251. data/lib/active_record/validations/associated.rb +4 -4
  252. data/lib/active_record/validations/numericality.rb +5 -4
  253. data/lib/active_record/validations/presence.rb +5 -28
  254. data/lib/active_record/validations/uniqueness.rb +51 -6
  255. data/lib/active_record/validations.rb +8 -4
  256. data/lib/active_record/version.rb +1 -1
  257. data/lib/active_record.rb +335 -32
  258. data/lib/arel/attributes/attribute.rb +0 -8
  259. data/lib/arel/crud.rb +28 -22
  260. data/lib/arel/delete_manager.rb +18 -4
  261. data/lib/arel/errors.rb +10 -0
  262. data/lib/arel/factory_methods.rb +4 -0
  263. data/lib/arel/filter_predications.rb +9 -0
  264. data/lib/arel/insert_manager.rb +2 -3
  265. data/lib/arel/nodes/and.rb +4 -0
  266. data/lib/arel/nodes/binary.rb +6 -1
  267. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  268. data/lib/arel/nodes/casted.rb +1 -1
  269. data/lib/arel/nodes/cte.rb +36 -0
  270. data/lib/arel/nodes/delete_statement.rb +12 -13
  271. data/lib/arel/nodes/filter.rb +10 -0
  272. data/lib/arel/nodes/fragments.rb +35 -0
  273. data/lib/arel/nodes/function.rb +1 -0
  274. data/lib/arel/nodes/homogeneous_in.rb +0 -8
  275. data/lib/arel/nodes/insert_statement.rb +2 -2
  276. data/lib/arel/nodes/leading_join.rb +8 -0
  277. data/lib/arel/nodes/node.rb +111 -2
  278. data/lib/arel/nodes/select_core.rb +2 -2
  279. data/lib/arel/nodes/select_statement.rb +2 -2
  280. data/lib/arel/nodes/sql_literal.rb +6 -0
  281. data/lib/arel/nodes/table_alias.rb +4 -0
  282. data/lib/arel/nodes/update_statement.rb +8 -3
  283. data/lib/arel/nodes.rb +5 -0
  284. data/lib/arel/predications.rb +13 -3
  285. data/lib/arel/select_manager.rb +10 -4
  286. data/lib/arel/table.rb +9 -6
  287. data/lib/arel/tree_manager.rb +0 -12
  288. data/lib/arel/update_manager.rb +18 -4
  289. data/lib/arel/visitors/dot.rb +80 -90
  290. data/lib/arel/visitors/mysql.rb +16 -3
  291. data/lib/arel/visitors/postgresql.rb +0 -10
  292. data/lib/arel/visitors/to_sql.rb +139 -19
  293. data/lib/arel/visitors/visitor.rb +2 -2
  294. data/lib/arel.rb +18 -3
  295. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  296. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  297. data/lib/rails/generators/active_record/migration.rb +3 -1
  298. data/lib/rails/generators/active_record/model/USAGE +113 -0
  299. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  300. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  301. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  302. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  303. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  304. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  305. metadata +92 -13
  306. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  307. data/lib/active_record/null_relation.rb +0 -67
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/enumerable"
4
- require "active_support/core_ext/hash/indifferent_access"
5
- require "active_support/core_ext/string/filters"
4
+ require "active_support/core_ext/module/delegation"
6
5
  require "active_support/parameter_filter"
7
6
  require "concurrent/map"
8
7
 
9
8
  module ActiveRecord
9
+ # = Active Record \Core
10
10
  module Core
11
11
  extend ActiveSupport::Concern
12
+ include ActiveModel::Access
12
13
 
13
14
  included do
14
15
  ##
@@ -17,26 +18,32 @@ module ActiveRecord
17
18
  # Accepts a logger conforming to the interface of Log4r which is then
18
19
  # passed on to any new database connections made and which can be
19
20
  # retrieved on both a class and instance level by calling +logger+.
20
- mattr_accessor :logger, instance_writer: false
21
+ class_attribute :logger, instance_writer: false
21
22
 
22
- ##
23
- # :singleton-method:
24
- #
25
- # Specifies if the methods calling database queries should be logged below
26
- # their relevant queries. Defaults to false.
27
- mattr_accessor :verbose_query_logs, instance_writer: false, default: false
23
+ class_attribute :_destroy_association_async_job, instance_accessor: false, default: "ActiveRecord::DestroyAssociationAsyncJob"
28
24
 
29
- ##
30
- # :singleton-method:
31
- #
32
- # Specifies the names of the queues used by background jobs.
33
- mattr_accessor :queues, instance_accessor: false, default: {}
25
+ # The job class used to destroy associations in the background.
26
+ def self.destroy_association_async_job
27
+ if _destroy_association_async_job.is_a?(String)
28
+ self._destroy_association_async_job = _destroy_association_async_job.constantize
29
+ end
30
+ _destroy_association_async_job
31
+ rescue NameError => error
32
+ raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
33
+ end
34
+
35
+ singleton_class.alias_method :destroy_association_async_job=, :_destroy_association_async_job=
36
+ delegate :destroy_association_async_job, to: :class
34
37
 
35
38
  ##
36
39
  # :singleton-method:
37
40
  #
38
- # Specifies the job used to destroy associations in the background
39
- class_attribute :destroy_association_async_job, instance_writer: false, instance_predicate: false, default: false
41
+ # Specifies the maximum number of records that will be destroyed in a
42
+ # single background job by the <tt>dependent: :destroy_async</tt>
43
+ # association option. When +nil+ (default), all dependent records will be
44
+ # destroyed in a single background job. If specified, the records to be
45
+ # destroyed will be split into multiple background jobs.
46
+ class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil
40
47
 
41
48
  ##
42
49
  # Contains the database configuration - as is typically stored in config/database.yml -
@@ -46,19 +53,19 @@ module ActiveRecord
46
53
  #
47
54
  # development:
48
55
  # adapter: sqlite3
49
- # database: db/development.sqlite3
56
+ # database: storage/development.sqlite3
50
57
  #
51
58
  # production:
52
59
  # adapter: sqlite3
53
- # database: db/production.sqlite3
60
+ # database: storage/production.sqlite3
54
61
  #
55
62
  # ...would result in ActiveRecord::Base.configurations to look like this:
56
63
  #
57
64
  # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
58
65
  # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
59
- # @name="primary", @config={adapter: "sqlite3", database: "db/development.sqlite3"}>,
66
+ # @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
60
67
  # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
61
- # @name="primary", @config={adapter: "sqlite3", database: "db/production.sqlite3"}>
68
+ # @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
62
69
  # ]>
63
70
  def self.configurations=(config)
64
71
  @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
@@ -72,80 +79,19 @@ module ActiveRecord
72
79
 
73
80
  ##
74
81
  # :singleton-method:
75
- # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
76
- # dates and times from the database. This is set to :utc by default.
77
- mattr_accessor :default_timezone, instance_writer: false, default: :utc
78
-
79
- ##
80
- # :singleton-method:
81
- # Specifies the format to use when dumping the database schema with Rails'
82
- # Rakefile. If :sql, the schema is dumped as (potentially database-
83
- # specific) SQL statements. If :ruby, the schema is dumped as an
84
- # ActiveRecord::Schema file which can be loaded into any database that
85
- # supports migrations. Use :ruby if you want to have different database
86
- # adapters for, e.g., your development and test environments.
87
- mattr_accessor :schema_format, instance_writer: false, default: :ruby
88
-
89
- ##
90
- # :singleton-method:
91
- # Specifies if an error should be raised if the query has an order being
92
- # ignored when doing batch queries. Useful in applications where the
93
- # scope being ignored is error-worthy, rather than a warning.
94
- mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
95
-
96
- ##
97
- # :singleton-method:
98
- # Specify whether or not to use timestamps for migration versions
99
- mattr_accessor :timestamped_migrations, instance_writer: false, default: true
100
-
101
- ##
102
- # :singleton-method:
103
- # Specify whether schema dump should happen at the end of the
104
- # db:migrate rails command. This is true by default, which is useful for the
105
- # development environment. This should ideally be false in the production
106
- # environment where dumping schema is rarely needed.
107
- mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
108
-
109
- ##
110
- # :singleton-method:
111
- # Specifies which database schemas to dump when calling db:schema:dump.
112
- # If the value is :schema_search_path (the default), any schemas listed in
113
- # schema_search_path are dumped. Use :all to dump all schemas regardless
114
- # of schema_search_path, or a string of comma separated schemas for a
115
- # custom list.
116
- mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
117
-
118
- ##
119
- # :singleton-method:
120
- # Specify a threshold for the size of query result sets. If the number of
121
- # records in the set exceeds the threshold, a warning is logged. This can
122
- # be used to identify queries which load thousands of records and
123
- # potentially cause memory bloat.
124
- mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
125
-
126
- ##
127
- # :singleton-method:
128
- # Show a warning when Rails couldn't parse your database.yml
129
- # for multiple databases.
130
- mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false
131
-
132
- mattr_accessor :maintain_test_schema, instance_accessor: false
82
+ # Force enumeration of all columns in SELECT statements.
83
+ # e.g. <tt>SELECT first_name, last_name FROM ...</tt> instead of <tt>SELECT * FROM ...</tt>
84
+ # This avoids +PreparedStatementCacheExpired+ errors when a column is added
85
+ # to the database while the app is running.
86
+ class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
133
87
 
134
88
  class_attribute :belongs_to_required_by_default, instance_accessor: false
135
89
 
136
- ##
137
- # :singleton-method:
138
- # Set the application to log or raise when an association violates strict loading.
139
- # Defaults to :raise.
140
- mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise
141
-
142
90
  class_attribute :strict_loading_by_default, instance_accessor: false, default: false
143
91
 
144
- mattr_accessor :writing_role, instance_accessor: false, default: :writing
92
+ class_attribute :has_many_inversing, instance_accessor: false, default: false
145
93
 
146
- mattr_accessor :reading_role, instance_accessor: false, default: :reading
147
-
148
- mattr_accessor :has_many_inversing, instance_accessor: false, default: false
94
+ class_attribute :run_commit_callbacks_on_first_saved_instances_in_transaction, instance_accessor: false, default: true
149
95
 
150
96
  class_attribute :default_connection_handler, instance_writer: false
151
97
 
@@ -153,40 +99,35 @@ module ActiveRecord
153
99
 
154
100
  class_attribute :default_shard, instance_writer: false
155
101
 
156
- mattr_accessor :legacy_connection_handling, instance_writer: false, default: true
157
-
158
- # Application configurable boolean that instructs the YAML Coder to use
159
- # an unsafe load if set to true.
160
- mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
102
+ class_attribute :shard_selector, instance_accessor: false, default: nil
161
103
 
162
- # Application configurable array that provides additional permitted classes
163
- # to Psych safe_load in the YAML Coder
164
- mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: [Symbol]
104
+ def self.application_record_class? # :nodoc:
105
+ if ActiveRecord.application_record_class
106
+ self == ActiveRecord.application_record_class
107
+ else
108
+ if defined?(ApplicationRecord) && self == ApplicationRecord
109
+ true
110
+ end
111
+ end
112
+ end
165
113
 
166
114
  self.filter_attributes = []
167
115
 
168
116
  def self.connection_handler
169
- Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
117
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
170
118
  end
171
119
 
172
120
  def self.connection_handler=(handler)
173
- Thread.current.thread_variable_set(:ar_connection_handler, handler)
121
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
174
122
  end
175
123
 
176
- def self.connection_handlers
177
- unless legacy_connection_handling
178
- raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
179
- end
180
-
181
- @@connection_handlers ||= {}
124
+ def self.asynchronous_queries_session # :nodoc:
125
+ asynchronous_queries_tracker.current_session
182
126
  end
183
127
 
184
- def self.connection_handlers=(handlers)
185
- unless legacy_connection_handling
186
- raise NotImplementedError, "The new connection handling does not setting support multiple connection handlers."
187
- end
188
-
189
- @@connection_handlers = handlers
128
+ def self.asynchronous_queries_tracker # :nodoc:
129
+ ActiveSupport::IsolatedExecutionState[:active_record_asynchronous_queries_tracker] ||= \
130
+ AsynchronousQueriesTracker.new
190
131
  end
191
132
 
192
133
  # Returns the symbol representing the current connected role.
@@ -199,16 +140,12 @@ module ActiveRecord
199
140
  # ActiveRecord::Base.current_role #=> :reading
200
141
  # end
201
142
  def self.current_role
202
- if ActiveRecord::Base.legacy_connection_handling
203
- connection_handlers.key(connection_handler) || default_role
204
- else
205
- connected_to_stack.reverse_each do |hash|
206
- return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
207
- return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes)
208
- end
209
-
210
- default_role
143
+ connected_to_stack.reverse_each do |hash|
144
+ return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
145
+ return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
211
146
  end
147
+
148
+ default_role
212
149
  end
213
150
 
214
151
  # Returns the symbol representing the current connected shard.
@@ -223,7 +160,7 @@ module ActiveRecord
223
160
  def self.current_shard
224
161
  connected_to_stack.reverse_each do |hash|
225
162
  return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
226
- return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_classes)
163
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
227
164
  end
228
165
 
229
166
  default_shard
@@ -240,24 +177,20 @@ module ActiveRecord
240
177
  # ActiveRecord::Base.current_preventing_writes #=> false
241
178
  # end
242
179
  def self.current_preventing_writes
243
- if legacy_connection_handling
244
- connection_handler.prevent_writes
245
- else
246
- connected_to_stack.reverse_each do |hash|
247
- return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
248
- return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_classes)
249
- end
250
-
251
- false
180
+ connected_to_stack.reverse_each do |hash|
181
+ return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
182
+ return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
252
183
  end
184
+
185
+ false
253
186
  end
254
187
 
255
188
  def self.connected_to_stack # :nodoc:
256
- if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack)
189
+ if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
257
190
  connected_to_stack
258
191
  else
259
192
  connected_to_stack = Concurrent::Array.new
260
- Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
193
+ ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
261
194
  connected_to_stack
262
195
  end
263
196
  end
@@ -266,7 +199,7 @@ module ActiveRecord
266
199
  @connection_class = b
267
200
  end
268
201
 
269
- def self.connection_class # :nodoc
202
+ def self.connection_class # :nodoc:
270
203
  @connection_class ||= false
271
204
  end
272
205
 
@@ -274,7 +207,7 @@ module ActiveRecord
274
207
  self.connection_class
275
208
  end
276
209
 
277
- def self.connection_classes # :nodoc:
210
+ def self.connection_class_for_self # :nodoc:
278
211
  klass = self
279
212
 
280
213
  until klass == Base
@@ -285,22 +218,14 @@ module ActiveRecord
285
218
  klass
286
219
  end
287
220
 
288
- def self.allow_unsafe_raw_sql # :nodoc:
289
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0")
290
- end
291
-
292
- def self.allow_unsafe_raw_sql=(value) # :nodoc:
293
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0")
294
- end
295
-
296
221
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
297
- self.default_role = writing_role
222
+ self.default_role = ActiveRecord.writing_role
298
223
  self.default_shard = :default
299
224
 
300
225
  def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
301
- case action_on_strict_loading_violation
226
+ case ActiveRecord.action_on_strict_loading_violation
302
227
  when :raise
303
- message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
228
+ message = reflection.strict_loading_violation_message(owner)
304
229
  raise ActiveRecord::StrictLoadingViolationError.new(message)
305
230
  when :log
306
231
  name = "strict_loading_violation.active_record"
@@ -314,19 +239,6 @@ module ActiveRecord
314
239
  @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
315
240
  end
316
241
 
317
- def inherited(child_class) # :nodoc:
318
- # initialize cache at class definition for thread safety
319
- child_class.initialize_find_by_cache
320
- unless child_class.base_class?
321
- klass = self
322
- until klass.base_class?
323
- klass.initialize_find_by_cache
324
- klass = klass.superclass
325
- end
326
- end
327
- super
328
- end
329
-
330
242
  def find(*ids) # :nodoc:
331
243
  # We don't have cache keys for this stuff yet
332
244
  return super unless ids.length == 1
@@ -336,14 +248,8 @@ module ActiveRecord
336
248
 
337
249
  return super if StatementCache.unsupported_value?(id)
338
250
 
339
- key = primary_key
340
-
341
- statement = cached_find_by_statement(key) { |params|
342
- where(key => params.bind).limit(1)
343
- }
344
-
345
- statement.execute([id], connection).first ||
346
- raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
251
+ cached_find_by([primary_key], [id]) ||
252
+ raise(RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}", name, primary_key, id))
347
253
  end
348
254
 
349
255
  def find_by(*args) # :nodoc:
@@ -375,21 +281,11 @@ module ActiveRecord
375
281
  h[key] = value
376
282
  end
377
283
 
378
- keys = hash.keys
379
- statement = cached_find_by_statement(keys) { |params|
380
- wheres = keys.index_with { params.bind }
381
- where(wheres).limit(1)
382
- }
383
-
384
- begin
385
- statement.execute(hash.values, connection).first
386
- rescue TypeError
387
- raise ActiveRecord::StatementInvalid
388
- end
284
+ cached_find_by(hash.keys, hash.values)
389
285
  end
390
286
 
391
287
  def find_by!(*args) # :nodoc:
392
- find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
288
+ find_by(*args) || where(*args).raise_record_not_found_exception!
393
289
  end
394
290
 
395
291
  def initialize_generated_modules # :nodoc:
@@ -408,10 +304,10 @@ module ActiveRecord
408
304
 
409
305
  # Returns columns which shouldn't be exposed while calling +#inspect+.
410
306
  def filter_attributes
411
- if defined?(@filter_attributes)
412
- @filter_attributes
413
- else
307
+ if @filter_attributes.nil?
414
308
  superclass.filter_attributes
309
+ else
310
+ @filter_attributes
415
311
  end
416
312
  end
417
313
 
@@ -422,13 +318,13 @@ module ActiveRecord
422
318
  end
423
319
 
424
320
  def inspection_filter # :nodoc:
425
- if defined?(@filter_attributes)
321
+ if @filter_attributes.nil?
322
+ superclass.inspection_filter
323
+ else
426
324
  @inspection_filter ||= begin
427
325
  mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
428
326
  ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
429
327
  end
430
- else
431
- superclass.inspection_filter
432
328
  end
433
329
  end
434
330
 
@@ -448,25 +344,11 @@ module ActiveRecord
448
344
  end
449
345
  end
450
346
 
451
- # Overwrite the default class equality method to provide support for decorated models.
452
- def ===(object) # :nodoc:
453
- object.is_a?(self)
454
- end
455
-
456
- # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
457
- #
458
- # class Post < ActiveRecord::Base
459
- # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
460
- # end
347
+ # Returns an instance of +Arel::Table+ loaded with the current table name.
461
348
  def arel_table # :nodoc:
462
349
  @arel_table ||= Arel::Table.new(table_name, klass: self)
463
350
  end
464
351
 
465
- def arel_attribute(name, table = arel_table) # :nodoc:
466
- table[name]
467
- end
468
- deprecate :arel_attribute
469
-
470
352
  def predicate_builder # :nodoc:
471
353
  @predicate_builder ||= PredicateBuilder.new(table_metadata)
472
354
  end
@@ -475,16 +357,34 @@ module ActiveRecord
475
357
  TypeCaster::Map.new(self)
476
358
  end
477
359
 
478
- def _internal? # :nodoc:
479
- false
480
- end
481
-
482
360
  def cached_find_by_statement(key, &block) # :nodoc:
483
361
  cache = @find_by_statement_cache[connection.prepared_statements]
484
362
  cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
485
363
  end
486
364
 
487
365
  private
366
+ def inherited(subclass)
367
+ super
368
+
369
+ # initialize cache at class definition for thread safety
370
+ subclass.initialize_find_by_cache
371
+ unless subclass.base_class?
372
+ klass = self
373
+ until klass.base_class?
374
+ klass.initialize_find_by_cache
375
+ klass = klass.superclass
376
+ end
377
+ end
378
+
379
+ subclass.class_eval do
380
+ @arel_table = nil
381
+ @predicate_builder = nil
382
+ @inspection_filter = nil
383
+ @filter_attributes = nil
384
+ @generated_association_methods = nil
385
+ end
386
+ end
387
+
488
388
  def relation
489
389
  relation = Relation.create(self)
490
390
 
@@ -498,6 +398,19 @@ module ActiveRecord
498
398
  def table_metadata
499
399
  TableMetadata.new(self, arel_table)
500
400
  end
401
+
402
+ def cached_find_by(keys, values)
403
+ statement = cached_find_by_statement(keys) { |params|
404
+ wheres = keys.index_with { params.bind }
405
+ where(wheres).limit(1)
406
+ }
407
+
408
+ begin
409
+ statement.execute(values, connection).first
410
+ rescue TypeError
411
+ raise ActiveRecord::StatementInvalid
412
+ end
413
+ end
501
414
  end
502
415
 
503
416
  # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
@@ -505,7 +418,7 @@ module ActiveRecord
505
418
  # In both instances, valid attribute keys are determined by the column names of the associated table --
506
419
  # hence you can't have attributes that aren't part of the table columns.
507
420
  #
508
- # ==== Example:
421
+ # ==== Example
509
422
  # # Instantiates a single new object
510
423
  # User.new(first_name: 'Jamie')
511
424
  def initialize(attributes = nil)
@@ -536,7 +449,7 @@ module ActiveRecord
536
449
  # post.init_with(coder)
537
450
  # post.title # => 'hello world'
538
451
  def init_with(coder, &block)
539
- coder = LegacyYamlAdapter.convert(self.class, coder)
452
+ coder = LegacyYamlAdapter.convert(coder)
540
453
  attributes = self.class.yaml_encoder.decode(coder)
541
454
  init_with_attributes(attributes, coder["new_record"], &block)
542
455
  end
@@ -583,12 +496,17 @@ module ActiveRecord
583
496
  # only, not its associations. The extent of a "deep" copy is application
584
497
  # specific and is therefore left to the application to implement according
585
498
  # to its need.
586
- # The dup method does not preserve the timestamps (created|updated)_(at|on).
499
+ # The dup method does not preserve the timestamps (created|updated)_(at|on)
500
+ # and locking column.
587
501
 
588
502
  ##
589
503
  def initialize_dup(other) # :nodoc:
590
504
  @attributes = @attributes.deep_dup
591
- @attributes.reset(@primary_key)
505
+ if self.class.composite_primary_key?
506
+ @primary_key.each { |key| @attributes.reset(key) }
507
+ else
508
+ @attributes.reset(@primary_key)
509
+ end
592
510
 
593
511
  _run_initialize_callbacks
594
512
 
@@ -630,7 +548,7 @@ module ActiveRecord
630
548
  def ==(comparison_object)
631
549
  super ||
632
550
  comparison_object.instance_of?(self.class) &&
633
- !id.nil? &&
551
+ primary_key_values_present? &&
634
552
  comparison_object.id == id
635
553
  end
636
554
  alias :eql? :==
@@ -638,7 +556,9 @@ module ActiveRecord
638
556
  # Delegates to id in order to allow two records of the same type and id to work with something like:
639
557
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
640
558
  def hash
641
- if id
559
+ id = self.id
560
+
561
+ if primary_key_values_present?
642
562
  self.class.hash ^ id.hash
643
563
  else
644
564
  super
@@ -689,11 +609,45 @@ module ActiveRecord
689
609
  # if the record tries to lazily load an association.
690
610
  #
691
611
  # user = User.first
692
- # user.strict_loading!
612
+ # user.strict_loading! # => true
613
+ # user.address.city
614
+ # => ActiveRecord::StrictLoadingViolationError
693
615
  # user.comments.to_a
694
616
  # => ActiveRecord::StrictLoadingViolationError
695
- def strict_loading!
696
- @strict_loading = true
617
+ #
618
+ # ==== Parameters
619
+ #
620
+ # * +value+ - Boolean specifying whether to enable or disable strict loading.
621
+ # * <tt>:mode</tt> - Symbol specifying strict loading mode. Defaults to :all. Using
622
+ # :n_plus_one_only mode will only raise an error if an association that
623
+ # will lead to an n plus one query is lazily loaded.
624
+ #
625
+ # ==== Examples
626
+ #
627
+ # user = User.first
628
+ # user.strict_loading!(false) # => false
629
+ # user.address.city # => "Tatooine"
630
+ # user.comments.to_a # => [#<Comment:0x00...]
631
+ #
632
+ # user.strict_loading!(mode: :n_plus_one_only)
633
+ # user.address.city # => "Tatooine"
634
+ # user.comments.to_a # => [#<Comment:0x00...]
635
+ # user.comments.first.ratings.to_a
636
+ # => ActiveRecord::StrictLoadingViolationError
637
+ def strict_loading!(value = true, mode: :all)
638
+ unless [:all, :n_plus_one_only].include?(mode)
639
+ raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
640
+ end
641
+
642
+ @strict_loading_mode = mode
643
+ @strict_loading = value
644
+ end
645
+
646
+ attr_reader :strict_loading_mode
647
+
648
+ # Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
649
+ def strict_loading_n_plus_one_only?
650
+ @strict_loading_mode == :n_plus_one_only
697
651
  end
698
652
 
699
653
  # Marks this record as read only.
@@ -710,11 +664,11 @@ module ActiveRecord
710
664
  # We check defined?(@attributes) not to issue warnings if the object is
711
665
  # allocated but not initialized.
712
666
  inspection = if defined?(@attributes) && @attributes
713
- self.class.attribute_names.collect do |name|
667
+ attribute_names.filter_map do |name|
714
668
  if _has_attribute?(name)
715
669
  "#{name}: #{attribute_for_inspect(name)}"
716
670
  end
717
- end.compact.join(", ")
671
+ end.join(", ")
718
672
  else
719
673
  "not initialized"
720
674
  end
@@ -747,15 +701,26 @@ module ActiveRecord
747
701
  end
748
702
  end
749
703
 
750
- # Returns a hash of the given methods with their names as keys and returned values as values.
751
- def slice(*methods)
752
- methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
753
- end
754
-
704
+ ##
705
+ # :method: values_at
706
+ #
707
+ # :call-seq: values_at(*methods)
708
+ #
755
709
  # Returns an array of the values returned by the given methods.
756
- def values_at(*methods)
757
- methods.flatten.map! { |method| public_send(method) }
758
- end
710
+ #
711
+ #--
712
+ # Implemented by ActiveModel::Access#values_at.
713
+
714
+ ##
715
+ # :method: slice
716
+ #
717
+ # :call-seq: slice(*methods)
718
+ #
719
+ # Returns a hash of the given methods with their names as keys and returned
720
+ # values as values.
721
+ #
722
+ #--
723
+ # Implemented by ActiveModel::Access#slice.
759
724
 
760
725
  private
761
726
  # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
@@ -771,16 +736,21 @@ module ActiveRecord
771
736
  end
772
737
 
773
738
  def init_internals
774
- @primary_key = self.class.primary_key
775
739
  @readonly = false
776
740
  @previously_new_record = false
777
741
  @destroyed = false
778
742
  @marked_for_destruction = false
779
743
  @destroyed_by_association = nil
780
744
  @_start_transaction_state = nil
781
- @strict_loading = self.class.strict_loading_by_default
782
745
 
783
- self.class.define_attribute_methods
746
+ klass = self.class
747
+
748
+ @primary_key = klass.primary_key
749
+ @strict_loading = klass.strict_loading_by_default
750
+ @strict_loading_mode = :all
751
+
752
+ klass.define_attribute_methods
753
+ klass.generate_alias_attributes
784
754
  end
785
755
 
786
756
  def initialize_internals_callback