activerecord 5.0.6 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,7 +1,9 @@
1
- require 'thread'
2
- require 'active_support/core_ext/hash/indifferent_access'
3
- require 'active_support/core_ext/object/duplicable'
4
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+ require "active_support/core_ext/string/filters"
5
+ require "active_support/parameter_filter"
6
+ require "concurrent/map"
5
7
 
6
8
  module ActiveRecord
7
9
  module Core
@@ -16,9 +18,16 @@ module ActiveRecord
16
18
  # retrieved on both a class and instance level by calling +logger+.
17
19
  mattr_accessor :logger, instance_writer: false
18
20
 
21
+ ##
22
+ # :singleton-method:
23
+ #
24
+ # Specifies if the methods calling database queries should be logged below
25
+ # their relevant queries. Defaults to false.
26
+ mattr_accessor :verbose_query_logs, instance_writer: false, default: false
27
+
19
28
  ##
20
29
  # Contains the database configuration - as is typically stored in config/database.yml -
21
- # as a Hash.
30
+ # as an ActiveRecord::DatabaseConfigurations object.
22
31
  #
23
32
  # For example, the following database.yml...
24
33
  #
@@ -32,22 +41,18 @@ module ActiveRecord
32
41
  #
33
42
  # ...would result in ActiveRecord::Base.configurations to look like this:
34
43
  #
35
- # {
36
- # 'development' => {
37
- # 'adapter' => 'sqlite3',
38
- # 'database' => 'db/development.sqlite3'
39
- # },
40
- # 'production' => {
41
- # 'adapter' => 'sqlite3',
42
- # 'database' => 'db/production.sqlite3'
43
- # }
44
- # }
44
+ # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
45
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
46
+ # @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>,
47
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
48
+ # @spec_name="primary", @config={"adapter"=>"mysql2", "database"=>"db/production.sqlite3"}>
49
+ # ]>
45
50
  def self.configurations=(config)
46
- @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
51
+ @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
47
52
  end
48
53
  self.configurations = {}
49
54
 
50
- # Returns fully resolved configurations hash
55
+ # Returns fully resolved ActiveRecord::DatabaseConfigurations object
51
56
  def self.configurations
52
57
  @@configurations
53
58
  end
@@ -56,8 +61,7 @@ module ActiveRecord
56
61
  # :singleton-method:
57
62
  # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
58
63
  # dates and times from the database. This is set to :utc by default.
59
- mattr_accessor :default_timezone, instance_writer: false
60
- self.default_timezone = :utc
64
+ mattr_accessor :default_timezone, instance_writer: false, default: :utc
61
65
 
62
66
  ##
63
67
  # :singleton-method:
@@ -67,31 +71,35 @@ module ActiveRecord
67
71
  # ActiveRecord::Schema file which can be loaded into any database that
68
72
  # supports migrations. Use :ruby if you want to have different database
69
73
  # adapters for, e.g., your development and test environments.
70
- mattr_accessor :schema_format, instance_writer: false
71
- self.schema_format = :ruby
74
+ mattr_accessor :schema_format, instance_writer: false, default: :ruby
72
75
 
73
76
  ##
74
77
  # :singleton-method:
75
- # Specifies if an error should be raised on query limit or order being
78
+ # Specifies if an error should be raised if the query has an order being
76
79
  # ignored when doing batch queries. Useful in applications where the
77
- # limit or scope being ignored is error-worthy, rather than a warning.
78
- mattr_accessor :error_on_ignored_order_or_limit, instance_writer: false
79
- self.error_on_ignored_order_or_limit = false
80
+ # scope being ignored is error-worthy, rather than a warning.
81
+ mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
82
+
83
+ # :singleton-method:
84
+ # Specify the behavior for unsafe raw query methods. Values are as follows
85
+ # deprecated - Warnings are logged when unsafe raw SQL is passed to
86
+ # query methods.
87
+ # disabled - Unsafe raw SQL passed to query methods results in
88
+ # UnknownAttributeReference exception.
89
+ mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
80
90
 
81
91
  ##
82
92
  # :singleton-method:
83
93
  # Specify whether or not to use timestamps for migration versions
84
- mattr_accessor :timestamped_migrations, instance_writer: false
85
- self.timestamped_migrations = true
94
+ mattr_accessor :timestamped_migrations, instance_writer: false, default: true
86
95
 
87
96
  ##
88
97
  # :singleton-method:
89
98
  # Specify whether schema dump should happen at the end of the
90
- # db:migrate rake task. This is true by default, which is useful for the
99
+ # db:migrate rails command. This is true by default, which is useful for the
91
100
  # development environment. This should ideally be false in the production
92
101
  # environment where dumping schema is rarely needed.
93
- mattr_accessor :dump_schema_after_migration, instance_writer: false
94
- self.dump_schema_after_migration = true
102
+ mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
95
103
 
96
104
  ##
97
105
  # :singleton-method:
@@ -100,8 +108,7 @@ module ActiveRecord
100
108
  # schema_search_path are dumped. Use :all to dump all schemas regardless
101
109
  # of schema_search_path, or a string of comma separated schemas for a
102
110
  # custom list.
103
- mattr_accessor :dump_schemas, instance_writer: false
104
- self.dump_schemas = :schema_search_path
111
+ mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
105
112
 
106
113
  ##
107
114
  # :singleton-method:
@@ -110,33 +117,35 @@ module ActiveRecord
110
117
  # be used to identify queries which load thousands of records and
111
118
  # potentially cause memory bloat.
112
119
  mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
113
- self.warn_on_records_fetched_greater_than = nil
114
120
 
115
121
  mattr_accessor :maintain_test_schema, instance_accessor: false
116
122
 
117
123
  mattr_accessor :belongs_to_required_by_default, instance_accessor: false
118
124
 
125
+ mattr_accessor :connection_handlers, instance_accessor: false, default: {}
126
+
127
+ mattr_accessor :writing_role, instance_accessor: false, default: :writing
128
+
129
+ mattr_accessor :reading_role, instance_accessor: false, default: :reading
130
+
119
131
  class_attribute :default_connection_handler, instance_writer: false
120
132
 
133
+ self.filter_attributes = []
134
+
121
135
  def self.connection_handler
122
- ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
136
+ Thread.current.thread_variable_get("ar_connection_handler") || default_connection_handler
123
137
  end
124
138
 
125
139
  def self.connection_handler=(handler)
126
- ActiveRecord::RuntimeRegistry.connection_handler = handler
140
+ Thread.current.thread_variable_set("ar_connection_handler", handler)
127
141
  end
128
142
 
129
143
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
130
144
  end
131
145
 
132
146
  module ClassMethods
133
- def allocate
134
- define_attribute_methods
135
- super
136
- end
137
-
138
147
  def initialize_find_by_cache # :nodoc:
139
- @find_by_statement_cache = { true => {}.extend(Mutex_m), false => {}.extend(Mutex_m) }
148
+ @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
140
149
  end
141
150
 
142
151
  def inherited(child_class) # :nodoc:
@@ -151,41 +160,33 @@ module ActiveRecord
151
160
  return super if block_given? ||
152
161
  primary_key.nil? ||
153
162
  scope_attributes? ||
154
- columns_hash.include?(inheritance_column) ||
155
- ids.first.kind_of?(Array)
156
-
157
- id = ids.first
158
- if ActiveRecord::Base === id
159
- id = id.id
160
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
161
- You are passing an instance of ActiveRecord::Base to `find`.
162
- Please pass the id of the object by calling `.id`.
163
- MSG
164
- end
163
+ columns_hash.key?(inheritance_column) && !base_class?
164
+
165
+ id = ids.first
166
+
167
+ return super if StatementCache.unsupported_value?(id)
165
168
 
166
169
  key = primary_key
167
170
 
168
171
  statement = cached_find_by_statement(key) { |params|
169
172
  where(key => params.bind).limit(1)
170
173
  }
171
- record = statement.execute([id], self, connection).first
174
+
175
+ record = statement.execute([id], connection)&.first
172
176
  unless record
173
- raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
174
- name, primary_key, id)
177
+ raise RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
175
178
  end
176
179
  record
177
- rescue RangeError
178
- raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
179
- name, primary_key)
180
180
  end
181
181
 
182
182
  def find_by(*args) # :nodoc:
183
- return super if scope_attributes? || reflect_on_all_aggregations.any?
183
+ return super if scope_attributes? || reflect_on_all_aggregations.any? ||
184
+ columns_hash.key?(inheritance_column) && !base_class?
184
185
 
185
186
  hash = args.first
186
187
 
187
188
  return super if !(Hash === hash) || hash.values.any? { |v|
188
- v.nil? || Array === v || Hash === v || Relation === v || Base === v
189
+ StatementCache.unsupported_value?(v)
189
190
  }
190
191
 
191
192
  # We can't cache Post.find_by(author: david) ...yet
@@ -200,32 +201,44 @@ module ActiveRecord
200
201
  where(wheres).limit(1)
201
202
  }
202
203
  begin
203
- statement.execute(hash.values, self, connection).first
204
+ statement.execute(hash.values, connection)&.first
204
205
  rescue TypeError
205
206
  raise ActiveRecord::StatementInvalid
206
- rescue RangeError
207
- nil
208
207
  end
209
208
  end
210
209
 
211
210
  def find_by!(*args) # :nodoc:
212
- find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}", name)
211
+ find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
213
212
  end
214
213
 
215
214
  def initialize_generated_modules # :nodoc:
216
215
  generated_association_methods
217
216
  end
218
217
 
219
- def generated_association_methods
218
+ def generated_association_methods # :nodoc:
220
219
  @generated_association_methods ||= begin
221
220
  mod = const_set(:GeneratedAssociationMethods, Module.new)
221
+ private_constant :GeneratedAssociationMethods
222
222
  include mod
223
+
223
224
  mod
224
225
  end
225
226
  end
226
227
 
228
+ # Returns columns which shouldn't be exposed while calling +#inspect+.
229
+ def filter_attributes
230
+ if defined?(@filter_attributes)
231
+ @filter_attributes
232
+ else
233
+ superclass.filter_attributes
234
+ end
235
+ end
236
+
237
+ # Specifies columns which shouldn't be exposed while calling +#inspect+.
238
+ attr_writer :filter_attributes
239
+
227
240
  # Returns a string like 'Post(id:integer, title:string, body:text)'
228
- def inspect
241
+ def inspect # :nodoc:
229
242
  if self == Base
230
243
  super
231
244
  elsif abstract_class?
@@ -233,39 +246,30 @@ module ActiveRecord
233
246
  elsif !connected?
234
247
  "#{super} (call '#{super}.connection' to establish a connection)"
235
248
  elsif table_exists?
236
- attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ', '
249
+ attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
237
250
  "#{super}(#{attr_list})"
238
251
  else
239
252
  "#{super}(Table doesn't exist)"
240
253
  end
241
254
  end
242
255
 
243
- # Overwrite the default class equality method to provide support for association proxies.
244
- def ===(object)
256
+ # Overwrite the default class equality method to provide support for decorated models.
257
+ def ===(object) # :nodoc:
245
258
  object.is_a?(self)
246
259
  end
247
260
 
248
261
  # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
249
262
  #
250
263
  # class Post < ActiveRecord::Base
251
- # scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) }
264
+ # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
252
265
  # end
253
266
  def arel_table # :nodoc:
254
267
  @arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
255
268
  end
256
269
 
257
- # Returns the Arel engine.
258
- def arel_engine # :nodoc:
259
- @arel_engine ||=
260
- if Base == self || connection_handler.retrieve_connection_pool(connection_specification_name)
261
- self
262
- else
263
- superclass.arel_engine
264
- end
265
- end
266
-
267
270
  def arel_attribute(name, table = arel_table) # :nodoc:
268
- name = attribute_alias(name) if attribute_alias?(name)
271
+ name = name.to_s
272
+ name = attribute_aliases[name] || name
269
273
  table[name]
270
274
  end
271
275
 
@@ -277,28 +281,31 @@ module ActiveRecord
277
281
  TypeCaster::Map.new(self)
278
282
  end
279
283
 
284
+ def _internal? # :nodoc:
285
+ false
286
+ end
287
+
280
288
  private
281
289
 
282
- def cached_find_by_statement(key, &block) # :nodoc:
283
- cache = @find_by_statement_cache[connection.prepared_statements]
284
- cache[key] || cache.synchronize {
285
- cache[key] ||= StatementCache.create(connection, &block)
286
- }
287
- end
290
+ def cached_find_by_statement(key, &block)
291
+ cache = @find_by_statement_cache[connection.prepared_statements]
292
+ cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
293
+ end
288
294
 
289
- def relation # :nodoc:
290
- relation = Relation.create(self, arel_table, predicate_builder)
295
+ def relation
296
+ relation = Relation.create(self)
291
297
 
292
- if finder_needs_type_condition? && !ignore_default_scope?
293
- relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
294
- else
295
- relation
298
+ if finder_needs_type_condition? && !ignore_default_scope?
299
+ relation.where!(type_condition)
300
+ relation.create_with!(inheritance_column.to_s => sti_name)
301
+ else
302
+ relation
303
+ end
296
304
  end
297
- end
298
305
 
299
- def table_metadata # :nodoc:
300
- TableMetadata.new(self, arel_table)
301
- end
306
+ def table_metadata
307
+ TableMetadata.new(self, arel_table)
308
+ end
302
309
  end
303
310
 
304
311
  # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
@@ -310,7 +317,7 @@ module ActiveRecord
310
317
  # # Instantiates a single new object
311
318
  # User.new(first_name: 'Jamie')
312
319
  def initialize(attributes = nil)
313
- self.class.define_attribute_methods
320
+ @new_record = true
314
321
  @attributes = self.class._default_attributes.deep_dup
315
322
 
316
323
  init_internals
@@ -336,15 +343,21 @@ module ActiveRecord
336
343
  # post = Post.allocate
337
344
  # post.init_with(coder)
338
345
  # post.title # => 'hello world'
339
- def init_with(coder)
346
+ def init_with(coder, &block)
340
347
  coder = LegacyYamlAdapter.convert(self.class, coder)
341
- @attributes = coder['attributes']
342
-
343
- init_internals
348
+ attributes = self.class.yaml_encoder.decode(coder)
349
+ init_with_attributes(attributes, coder["new_record"], &block)
350
+ end
344
351
 
345
- @new_record = coder['new_record']
352
+ ##
353
+ # Initialize an empty model object from +attributes+.
354
+ # +attributes+ should be an attributes object, and unlike the
355
+ # `initialize` method, no assignment calls are made per attribute.
356
+ def init_with_attributes(attributes, new_record = false) # :nodoc:
357
+ @new_record = new_record
358
+ @attributes = attributes
346
359
 
347
- self.class.define_attribute_methods
360
+ init_internals
348
361
 
349
362
  yield self if block_given?
350
363
 
@@ -383,12 +396,14 @@ module ActiveRecord
383
396
  ##
384
397
  def initialize_dup(other) # :nodoc:
385
398
  @attributes = @attributes.deep_dup
386
- @attributes.reset(self.class.primary_key)
399
+ @attributes.reset(@primary_key)
387
400
 
388
401
  _run_initialize_callbacks
389
402
 
390
- @new_record = true
391
- @destroyed = false
403
+ @new_record = true
404
+ @destroyed = false
405
+ @_start_transaction_state = nil
406
+ @transaction_state = nil
392
407
 
393
408
  super
394
409
  end
@@ -406,11 +421,9 @@ module ActiveRecord
406
421
  # Post.new.encode_with(coder)
407
422
  # coder # => {"attributes" => {"id" => nil, ... }}
408
423
  def encode_with(coder)
409
- # FIXME: Remove this when we better serialize attributes
410
- coder['raw_attributes'] = attributes_before_type_cast
411
- coder['attributes'] = @attributes
412
- coder['new_record'] = new_record?
413
- coder['active_record_yaml_version'] = 1
424
+ self.class.yaml_encoder.encode(@attributes, coder)
425
+ coder["new_record"] = new_record?
426
+ coder["active_record_yaml_version"] = 2
414
427
  end
415
428
 
416
429
  # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
@@ -434,7 +447,7 @@ module ActiveRecord
434
447
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
435
448
  def hash
436
449
  if id
437
- id.hash
450
+ self.class.hash ^ id.hash
438
451
  else
439
452
  super
440
453
  end
@@ -450,18 +463,27 @@ module ActiveRecord
450
463
 
451
464
  # Returns +true+ if the attributes hash has been frozen.
452
465
  def frozen?
466
+ sync_with_transaction_state if @transaction_state&.finalized?
453
467
  @attributes.frozen?
454
468
  end
455
469
 
456
470
  # Allows sort on objects
457
471
  def <=>(other_object)
458
472
  if other_object.is_a?(self.class)
459
- self.to_key <=> other_object.to_key
473
+ to_key <=> other_object.to_key
460
474
  else
461
475
  super
462
476
  end
463
477
  end
464
478
 
479
+ def present? # :nodoc:
480
+ true
481
+ end
482
+
483
+ def blank? # :nodoc:
484
+ false
485
+ end
486
+
465
487
  # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
466
488
  # attributes will be marked as read only since they cannot be saved.
467
489
  def readonly?
@@ -482,14 +504,22 @@ module ActiveRecord
482
504
  # We check defined?(@attributes) not to issue warnings if the object is
483
505
  # allocated but not initialized.
484
506
  inspection = if defined?(@attributes) && @attributes
485
- self.class.column_names.collect { |name|
486
- if has_attribute?(name)
487
- "#{name}: #{attribute_for_inspect(name)}"
488
- end
489
- }.compact.join(", ")
490
- else
491
- "not initialized"
492
- end
507
+ self.class.attribute_names.collect do |name|
508
+ if has_attribute?(name)
509
+ attr = _read_attribute(name)
510
+ value = if attr.nil?
511
+ attr.inspect
512
+ else
513
+ attr = format_for_inspect(attr)
514
+ inspection_filter.filter_param(name, attr)
515
+ end
516
+ "#{name}: #{value}"
517
+ end
518
+ end.compact.join(", ")
519
+ else
520
+ "not initialized"
521
+ end
522
+
493
523
  "#<#{self.class} #{inspection}>"
494
524
  end
495
525
 
@@ -499,65 +529,75 @@ module ActiveRecord
499
529
  return super if custom_inspect_method_defined?
500
530
  pp.object_address_group(self) do
501
531
  if defined?(@attributes) && @attributes
502
- column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
503
- pp.seplist(column_names, proc { pp.text ',' }) do |column_name|
504
- column_value = read_attribute(column_name)
505
- pp.breakable ' '
532
+ attr_names = self.class.attribute_names.select { |name| has_attribute?(name) }
533
+ pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
534
+ pp.breakable " "
506
535
  pp.group(1) do
507
- pp.text column_name
508
- pp.text ':'
536
+ pp.text attr_name
537
+ pp.text ":"
509
538
  pp.breakable
510
- pp.pp column_value
539
+ value = _read_attribute(attr_name)
540
+ value = inspection_filter.filter_param(attr_name, value) unless value.nil?
541
+ pp.pp value
511
542
  end
512
543
  end
513
544
  else
514
- pp.breakable ' '
515
- pp.text 'not initialized'
545
+ pp.breakable " "
546
+ pp.text "not initialized"
516
547
  end
517
548
  end
518
549
  end
519
550
 
520
551
  # Returns a hash of the given methods with their names as keys and returned values as values.
521
552
  def slice(*methods)
522
- Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
553
+ Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
523
554
  end
524
555
 
525
556
  private
526
557
 
527
- # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
528
- # of the array, and then rescues from the possible NoMethodError. If those elements are
529
- # ActiveRecord::Base's, then this triggers the various method_missing's that we have,
530
- # which significantly impacts upon performance.
531
- #
532
- # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
533
- #
534
- # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
535
- def to_ary # :nodoc:
536
- nil
537
- end
558
+ # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
559
+ # the array, and then rescues from the possible +NoMethodError+. If those elements are
560
+ # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
561
+ # which significantly impacts upon performance.
562
+ #
563
+ # So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
564
+ #
565
+ # See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
566
+ def to_ary
567
+ nil
568
+ end
538
569
 
539
- def init_internals
540
- @readonly = false
541
- @destroyed = false
542
- @marked_for_destruction = false
543
- @destroyed_by_association = nil
544
- @new_record = true
545
- @txn = nil
546
- @_start_transaction_state = {}
547
- @transaction_state = nil
548
- end
570
+ def init_internals
571
+ @primary_key = self.class.primary_key
572
+ @readonly = false
573
+ @destroyed = false
574
+ @marked_for_destruction = false
575
+ @destroyed_by_association = nil
576
+ @_start_transaction_state = nil
577
+ @transaction_state = nil
549
578
 
550
- def initialize_internals_callback
551
- end
579
+ self.class.define_attribute_methods
580
+ end
552
581
 
553
- def thaw
554
- if frozen?
555
- @attributes = @attributes.dup
582
+ def initialize_internals_callback
556
583
  end
557
- end
558
584
 
559
- def custom_inspect_method_defined?
560
- self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
561
- end
585
+ def custom_inspect_method_defined?
586
+ self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
587
+ end
588
+
589
+ class InspectionMask < DelegateClass(::String)
590
+ def pretty_print(pp)
591
+ pp.text __getobj__
592
+ end
593
+ end
594
+ private_constant :InspectionMask
595
+
596
+ def inspection_filter
597
+ @inspection_filter ||= begin
598
+ mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
599
+ ActiveSupport::ParameterFilter.new(self.class.filter_attributes, mask: mask)
600
+ end
601
+ end
562
602
  end
563
603
  end