activerecord 6.1.6 → 7.1.2

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