activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,7 +1,10 @@
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/enumerable"
4
+ require "active_support/core_ext/hash/indifferent_access"
5
+ require "active_support/core_ext/string/filters"
6
+ require "active_support/parameter_filter"
7
+ require "concurrent/map"
5
8
 
6
9
  module ActiveRecord
7
10
  module Core
@@ -16,9 +19,28 @@ module ActiveRecord
16
19
  # retrieved on both a class and instance level by calling +logger+.
17
20
  mattr_accessor :logger, instance_writer: false
18
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
28
+
29
+ ##
30
+ # :singleton-method:
31
+ #
32
+ # Specifies the names of the queues used by background jobs.
33
+ mattr_accessor :queues, instance_accessor: false, default: {}
34
+
35
+ ##
36
+ # :singleton-method:
37
+ #
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
40
+
19
41
  ##
20
42
  # Contains the database configuration - as is typically stored in config/database.yml -
21
- # as a Hash.
43
+ # as an ActiveRecord::DatabaseConfigurations object.
22
44
  #
23
45
  # For example, the following database.yml...
24
46
  #
@@ -32,22 +54,18 @@ module ActiveRecord
32
54
  #
33
55
  # ...would result in ActiveRecord::Base.configurations to look like this:
34
56
  #
35
- # {
36
- # 'development' => {
37
- # 'adapter' => 'sqlite3',
38
- # 'database' => 'db/development.sqlite3'
39
- # },
40
- # 'production' => {
41
- # 'adapter' => 'sqlite3',
42
- # 'database' => 'db/production.sqlite3'
43
- # }
44
- # }
57
+ # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
58
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
59
+ # @name="primary", @config={adapter: "sqlite3", database: "db/development.sqlite3"}>,
60
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
61
+ # @name="primary", @config={adapter: "sqlite3", database: "db/production.sqlite3"}>
62
+ # ]>
45
63
  def self.configurations=(config)
46
- @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
64
+ @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
47
65
  end
48
66
  self.configurations = {}
49
67
 
50
- # Returns fully resolved configurations hash
68
+ # Returns fully resolved ActiveRecord::DatabaseConfigurations object
51
69
  def self.configurations
52
70
  @@configurations
53
71
  end
@@ -56,8 +74,7 @@ module ActiveRecord
56
74
  # :singleton-method:
57
75
  # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
58
76
  # 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
77
+ mattr_accessor :default_timezone, instance_writer: false, default: :utc
61
78
 
62
79
  ##
63
80
  # :singleton-method:
@@ -67,149 +84,348 @@ module ActiveRecord
67
84
  # ActiveRecord::Schema file which can be loaded into any database that
68
85
  # supports migrations. Use :ruby if you want to have different database
69
86
  # adapters for, e.g., your development and test environments.
70
- mattr_accessor :schema_format, instance_writer: false
71
- self.schema_format = :ruby
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
72
95
 
73
96
  ##
74
97
  # :singleton-method:
75
98
  # Specify whether or not to use timestamps for migration versions
76
- mattr_accessor :timestamped_migrations, instance_writer: false
77
- self.timestamped_migrations = true
99
+ mattr_accessor :timestamped_migrations, instance_writer: false, default: true
78
100
 
79
101
  ##
80
102
  # :singleton-method:
81
103
  # Specify whether schema dump should happen at the end of the
82
- # db:migrate rake task. This is true by default, which is useful for the
104
+ # db:migrate rails command. This is true by default, which is useful for the
83
105
  # development environment. This should ideally be false in the production
84
106
  # environment where dumping schema is rarely needed.
85
- mattr_accessor :dump_schema_after_migration, instance_writer: false
86
- self.dump_schema_after_migration = true
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
87
131
 
88
132
  mattr_accessor :maintain_test_schema, instance_accessor: false
89
133
 
90
- def self.disable_implicit_join_references=(value)
91
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
92
- Implicit join references were removed with Rails 4.1.
93
- Make sure to remove this configuration because it does nothing.
94
- MSG
95
- end
134
+ class_attribute :belongs_to_required_by_default, instance_accessor: false
135
+
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
+ class_attribute :strict_loading_by_default, instance_accessor: false, default: false
143
+
144
+ mattr_accessor :writing_role, instance_accessor: false, default: :writing
145
+
146
+ mattr_accessor :reading_role, instance_accessor: false, default: :reading
147
+
148
+ mattr_accessor :has_many_inversing, instance_accessor: false, default: false
96
149
 
97
150
  class_attribute :default_connection_handler, instance_writer: false
98
- class_attribute :find_by_statement_cache
151
+
152
+ class_attribute :default_role, instance_writer: false
153
+
154
+ class_attribute :default_shard, instance_writer: false
155
+
156
+ mattr_accessor :legacy_connection_handling, instance_writer: false, default: true
157
+
158
+ self.filter_attributes = []
99
159
 
100
160
  def self.connection_handler
101
- ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
161
+ Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
102
162
  end
103
163
 
104
164
  def self.connection_handler=(handler)
105
- ActiveRecord::RuntimeRegistry.connection_handler = handler
165
+ Thread.current.thread_variable_set(:ar_connection_handler, handler)
166
+ end
167
+
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 ||= {}
174
+ end
175
+
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
182
+ end
183
+
184
+ # Returns the symbol representing the current connected role.
185
+ #
186
+ # ActiveRecord::Base.connected_to(role: :writing) do
187
+ # ActiveRecord::Base.current_role #=> :writing
188
+ # end
189
+ #
190
+ # ActiveRecord::Base.connected_to(role: :reading) do
191
+ # ActiveRecord::Base.current_role #=> :reading
192
+ # end
193
+ 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
203
+ end
204
+ end
205
+
206
+ # Returns the symbol representing the current connected shard.
207
+ #
208
+ # ActiveRecord::Base.connected_to(role: :reading) do
209
+ # ActiveRecord::Base.current_shard #=> :default
210
+ # end
211
+ #
212
+ # ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
213
+ # ActiveRecord::Base.current_shard #=> :one
214
+ # end
215
+ def self.current_shard
216
+ connected_to_stack.reverse_each do |hash|
217
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
218
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_classes)
219
+ end
220
+
221
+ default_shard
222
+ end
223
+
224
+ # Returns the symbol representing the current setting for
225
+ # preventing writes.
226
+ #
227
+ # ActiveRecord::Base.connected_to(role: :reading) do
228
+ # ActiveRecord::Base.current_preventing_writes #=> true
229
+ # end
230
+ #
231
+ # ActiveRecord::Base.connected_to(role: :writing) do
232
+ # ActiveRecord::Base.current_preventing_writes #=> false
233
+ # end
234
+ 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
244
+ end
245
+ end
246
+
247
+ def self.connected_to_stack # :nodoc:
248
+ if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack)
249
+ connected_to_stack
250
+ else
251
+ connected_to_stack = Concurrent::Array.new
252
+ Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
253
+ connected_to_stack
254
+ end
255
+ end
256
+
257
+ def self.connection_class=(b) # :nodoc:
258
+ @connection_class = b
259
+ end
260
+
261
+ def self.connection_class # :nodoc
262
+ @connection_class ||= false
263
+ end
264
+
265
+ def self.connection_class? # :nodoc:
266
+ self.connection_class
267
+ end
268
+
269
+ def self.connection_classes # :nodoc:
270
+ klass = self
271
+
272
+ until klass == Base
273
+ break if klass.connection_class?
274
+ klass = klass.superclass
275
+ end
276
+
277
+ klass
278
+ end
279
+
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 6.2")
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 6.2")
106
286
  end
107
287
 
108
288
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
289
+ self.default_role = writing_role
290
+ self.default_shard = :default
291
+
292
+ def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
293
+ case action_on_strict_loading_violation
294
+ when :raise
295
+ message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
296
+ raise ActiveRecord::StrictLoadingViolationError.new(message)
297
+ when :log
298
+ name = "strict_loading_violation.active_record"
299
+ ActiveSupport::Notifications.instrument(name, owner: owner, reflection: reflection)
300
+ end
301
+ end
109
302
  end
110
303
 
111
304
  module ClassMethods
112
- def allocate
113
- define_attribute_methods
114
- super
115
- end
116
-
117
305
  def initialize_find_by_cache # :nodoc:
118
- self.find_by_statement_cache = {}.extend(Mutex_m)
306
+ @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
119
307
  end
120
308
 
121
309
  def inherited(child_class) # :nodoc:
310
+ # initialize cache at class definition for thread safety
122
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
123
319
  super
124
320
  end
125
321
 
126
322
  def find(*ids) # :nodoc:
127
323
  # We don't have cache keys for this stuff yet
128
324
  return super unless ids.length == 1
129
- # Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
130
- return super if ids.first.kind_of?(Symbol)
131
- return super if block_given? ||
132
- primary_key.nil? ||
133
- default_scopes.any? ||
134
- current_scope ||
135
- columns_hash.include?(inheritance_column) ||
136
- ids.first.kind_of?(Array)
137
-
138
- id = ids.first
139
- if ActiveRecord::Base === id
140
- id = id.id
141
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
142
- You are passing an instance of ActiveRecord::Base to `find`.
143
- Please pass the id of the object by calling `.id`
144
- MSG
145
- end
325
+ return super if block_given? || primary_key.nil? || scope_attributes?
326
+
327
+ id = ids.first
328
+
329
+ return super if StatementCache.unsupported_value?(id)
330
+
146
331
  key = primary_key
147
332
 
148
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
149
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
150
- where(key => params.bind).limit(1)
151
- }
333
+ statement = cached_find_by_statement(key) { |params|
334
+ where(key => params.bind).limit(1)
152
335
  }
153
- record = s.execute([id], self, connection).first
154
- unless record
155
- raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
156
- end
157
- record
158
- rescue RangeError
159
- raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
336
+
337
+ statement.execute([id], connection).first ||
338
+ raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
160
339
  end
161
340
 
162
341
  def find_by(*args) # :nodoc:
163
- return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
164
- return super if default_scopes.any?
342
+ return super if scope_attributes?
165
343
 
166
344
  hash = args.first
345
+ return super unless Hash === hash
167
346
 
168
- return super if hash.values.any? { |v|
169
- v.nil? || Array === v || Hash === v
170
- }
347
+ hash = hash.each_with_object({}) do |(key, value), h|
348
+ key = key.to_s
349
+ key = attribute_aliases[key] || key
171
350
 
172
- # We can't cache Post.find_by(author: david) ...yet
173
- return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
351
+ return super if reflect_on_aggregation(key)
174
352
 
175
- key = hash.keys
353
+ reflection = _reflect_on_association(key)
176
354
 
177
- klass = self
178
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
179
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
180
- wheres = key.each_with_object({}) { |param,o|
181
- o[param] = params.bind
182
- }
183
- klass.where(wheres).limit(1)
184
- }
355
+ if !reflection
356
+ value = value.id if value.respond_to?(:id)
357
+ elsif reflection.belongs_to? && !reflection.polymorphic?
358
+ key = reflection.join_foreign_key
359
+ pkey = reflection.join_primary_key
360
+ value = value.public_send(pkey) if value.respond_to?(pkey)
361
+ end
362
+
363
+ if !columns_hash.key?(key) || StatementCache.unsupported_value?(value)
364
+ return super
365
+ end
366
+
367
+ h[key] = value
368
+ end
369
+
370
+ keys = hash.keys
371
+ statement = cached_find_by_statement(keys) { |params|
372
+ wheres = keys.index_with { params.bind }
373
+ where(wheres).limit(1)
185
374
  }
375
+
186
376
  begin
187
- s.execute(hash.values, self, connection).first
188
- rescue TypeError => e
189
- raise ActiveRecord::StatementInvalid.new(e.message, e)
190
- rescue RangeError
191
- nil
377
+ statement.execute(hash.values, connection).first
378
+ rescue TypeError
379
+ raise ActiveRecord::StatementInvalid
192
380
  end
193
381
  end
194
382
 
195
383
  def find_by!(*args) # :nodoc:
196
- find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
384
+ find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
197
385
  end
198
386
 
199
387
  def initialize_generated_modules # :nodoc:
200
388
  generated_association_methods
201
389
  end
202
390
 
203
- def generated_association_methods
391
+ def generated_association_methods # :nodoc:
204
392
  @generated_association_methods ||= begin
205
393
  mod = const_set(:GeneratedAssociationMethods, Module.new)
394
+ private_constant :GeneratedAssociationMethods
206
395
  include mod
396
+
207
397
  mod
208
398
  end
209
399
  end
210
400
 
401
+ # Returns columns which shouldn't be exposed while calling +#inspect+.
402
+ def filter_attributes
403
+ if defined?(@filter_attributes)
404
+ @filter_attributes
405
+ else
406
+ superclass.filter_attributes
407
+ end
408
+ end
409
+
410
+ # Specifies columns which shouldn't be exposed while calling +#inspect+.
411
+ def filter_attributes=(filter_attributes)
412
+ @inspection_filter = nil
413
+ @filter_attributes = filter_attributes
414
+ end
415
+
416
+ def inspection_filter # :nodoc:
417
+ if defined?(@filter_attributes)
418
+ @inspection_filter ||= begin
419
+ mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
420
+ ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
421
+ end
422
+ else
423
+ superclass.inspection_filter
424
+ end
425
+ end
426
+
211
427
  # Returns a string like 'Post(id:integer, title:string, body:text)'
212
- def inspect
428
+ def inspect # :nodoc:
213
429
  if self == Base
214
430
  super
215
431
  elsif abstract_class?
@@ -217,48 +433,63 @@ module ActiveRecord
217
433
  elsif !connected?
218
434
  "#{super} (call '#{super}.connection' to establish a connection)"
219
435
  elsif table_exists?
220
- attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
436
+ attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
221
437
  "#{super}(#{attr_list})"
222
438
  else
223
439
  "#{super}(Table doesn't exist)"
224
440
  end
225
441
  end
226
442
 
227
- # Overwrite the default class equality method to provide support for association proxies.
228
- def ===(object)
443
+ # Overwrite the default class equality method to provide support for decorated models.
444
+ def ===(object) # :nodoc:
229
445
  object.is_a?(self)
230
446
  end
231
447
 
232
448
  # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
233
449
  #
234
450
  # class Post < ActiveRecord::Base
235
- # scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) }
451
+ # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
236
452
  # end
237
453
  def arel_table # :nodoc:
238
- @arel_table ||= Arel::Table.new(table_name, arel_engine)
454
+ @arel_table ||= Arel::Table.new(table_name, klass: self)
239
455
  end
240
456
 
241
- # Returns the Arel engine.
242
- def arel_engine # :nodoc:
243
- @arel_engine ||=
244
- if Base == self || connection_handler.retrieve_connection_pool(self)
245
- self
246
- else
247
- superclass.arel_engine
248
- end
457
+ def arel_attribute(name, table = arel_table) # :nodoc:
458
+ table[name]
459
+ end
460
+ deprecate :arel_attribute
461
+
462
+ def predicate_builder # :nodoc:
463
+ @predicate_builder ||= PredicateBuilder.new(table_metadata)
464
+ end
465
+
466
+ def type_caster # :nodoc:
467
+ TypeCaster::Map.new(self)
468
+ end
469
+
470
+ def _internal? # :nodoc:
471
+ false
472
+ end
473
+
474
+ def cached_find_by_statement(key, &block) # :nodoc:
475
+ cache = @find_by_statement_cache[connection.prepared_statements]
476
+ cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
249
477
  end
250
478
 
251
479
  private
480
+ def relation
481
+ relation = Relation.create(self)
252
482
 
253
- def relation #:nodoc:
254
- relation = Relation.create(self, arel_table)
483
+ if finder_needs_type_condition? && !ignore_default_scope?
484
+ relation.where!(type_condition)
485
+ else
486
+ relation
487
+ end
488
+ end
255
489
 
256
- if finder_needs_type_condition?
257
- relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
258
- else
259
- relation
490
+ def table_metadata
491
+ TableMetadata.new(self, arel_table)
260
492
  end
261
- end
262
493
  end
263
494
 
264
495
  # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
@@ -269,16 +500,14 @@ module ActiveRecord
269
500
  # ==== Example:
270
501
  # # Instantiates a single new object
271
502
  # User.new(first_name: 'Jamie')
272
- def initialize(attributes = nil, options = {})
273
- @attributes = self.class._default_attributes.dup
274
- self.class.define_attribute_methods
503
+ def initialize(attributes = nil)
504
+ @new_record = true
505
+ @attributes = self.class._default_attributes.deep_dup
275
506
 
276
507
  init_internals
277
508
  initialize_internals_callback
278
509
 
279
- # +options+ argument is only needed to make protected_attributes gem easier to hook.
280
- # Remove it when we drop support to this gem.
281
- init_attributes(attributes, options) if attributes
510
+ assign_attributes(attributes) if attributes
282
511
 
283
512
  yield self if block_given?
284
513
  _run_initialize_callbacks
@@ -286,7 +515,7 @@ module ActiveRecord
286
515
 
287
516
  # Initialize an empty model object from +coder+. +coder+ should be
288
517
  # the result of previously encoding an Active Record model, using
289
- # `encode_with`
518
+ # #encode_with.
290
519
  #
291
520
  # class Post < ActiveRecord::Base
292
521
  # end
@@ -298,15 +527,23 @@ module ActiveRecord
298
527
  # post = Post.allocate
299
528
  # post.init_with(coder)
300
529
  # post.title # => 'hello world'
301
- def init_with(coder)
530
+ def init_with(coder, &block)
302
531
  coder = LegacyYamlAdapter.convert(self.class, coder)
303
- @attributes = coder['attributes']
532
+ attributes = self.class.yaml_encoder.decode(coder)
533
+ init_with_attributes(attributes, coder["new_record"], &block)
534
+ end
304
535
 
305
- init_internals
536
+ ##
537
+ # Initialize an empty model object from +attributes+.
538
+ # +attributes+ should be an attributes object, and unlike the
539
+ # `initialize` method, no assignment calls are made per attribute.
540
+ def init_with_attributes(attributes, new_record = false) # :nodoc:
541
+ @new_record = new_record
542
+ @attributes = attributes
306
543
 
307
- @new_record = coder['new_record']
544
+ init_internals
308
545
 
309
- self.class.define_attribute_methods
546
+ yield self if block_given?
310
547
 
311
548
  _run_find_callbacks
312
549
  _run_initialize_callbacks
@@ -342,23 +579,22 @@ module ActiveRecord
342
579
 
343
580
  ##
344
581
  def initialize_dup(other) # :nodoc:
345
- @attributes = @attributes.dup
346
- @attributes.reset(self.class.primary_key)
582
+ @attributes = @attributes.deep_dup
583
+ @attributes.reset(@primary_key)
347
584
 
348
585
  _run_initialize_callbacks
349
586
 
350
- @aggregation_cache = {}
351
- @association_cache = {}
352
-
353
- @new_record = true
354
- @destroyed = false
587
+ @new_record = true
588
+ @previously_new_record = false
589
+ @destroyed = false
590
+ @_start_transaction_state = nil
355
591
 
356
592
  super
357
593
  end
358
594
 
359
595
  # Populate +coder+ with attributes about this record that should be
360
596
  # serialized. The structure of +coder+ defined in this method is
361
- # guaranteed to match the structure of +coder+ passed to the +init_with+
597
+ # guaranteed to match the structure of +coder+ passed to the #init_with
362
598
  # method.
363
599
  #
364
600
  # Example:
@@ -369,11 +605,9 @@ module ActiveRecord
369
605
  # Post.new.encode_with(coder)
370
606
  # coder # => {"attributes" => {"id" => nil, ... }}
371
607
  def encode_with(coder)
372
- # FIXME: Remove this when we better serialize attributes
373
- coder['raw_attributes'] = attributes_before_type_cast
374
- coder['attributes'] = @attributes
375
- coder['new_record'] = new_record?
376
- coder['active_record_yaml_version'] = 0
608
+ self.class.yaml_encoder.encode(@attributes, coder)
609
+ coder["new_record"] = new_record?
610
+ coder["active_record_yaml_version"] = 2
377
611
  end
378
612
 
379
613
  # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
@@ -397,7 +631,7 @@ module ActiveRecord
397
631
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
398
632
  def hash
399
633
  if id
400
- id.hash
634
+ self.class.hash ^ id.hash
401
635
  else
402
636
  super
403
637
  end
@@ -419,18 +653,41 @@ module ActiveRecord
419
653
  # Allows sort on objects
420
654
  def <=>(other_object)
421
655
  if other_object.is_a?(self.class)
422
- self.to_key <=> other_object.to_key
656
+ to_key <=> other_object.to_key
423
657
  else
424
658
  super
425
659
  end
426
660
  end
427
661
 
428
- # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
429
- # attributes will be marked as read only since they cannot be saved.
662
+ def present? # :nodoc:
663
+ true
664
+ end
665
+
666
+ def blank? # :nodoc:
667
+ false
668
+ end
669
+
670
+ # Returns +true+ if the record is read only.
430
671
  def readonly?
431
672
  @readonly
432
673
  end
433
674
 
675
+ # Returns +true+ if the record is in strict_loading mode.
676
+ def strict_loading?
677
+ @strict_loading
678
+ end
679
+
680
+ # Sets the record to strict_loading mode. This will raise an error
681
+ # if the record tries to lazily load an association.
682
+ #
683
+ # user = User.first
684
+ # user.strict_loading!
685
+ # user.comments.to_a
686
+ # => ActiveRecord::StrictLoadingViolationError
687
+ def strict_loading!
688
+ @strict_loading = true
689
+ end
690
+
434
691
  # Marks this record as read only.
435
692
  def readonly!
436
693
  @readonly = true
@@ -445,135 +702,95 @@ module ActiveRecord
445
702
  # We check defined?(@attributes) not to issue warnings if the object is
446
703
  # allocated but not initialized.
447
704
  inspection = if defined?(@attributes) && @attributes
448
- self.class.column_names.collect { |name|
449
- if has_attribute?(name)
450
- "#{name}: #{attribute_for_inspect(name)}"
451
- end
452
- }.compact.join(", ")
453
- else
454
- "not initialized"
455
- end
705
+ self.class.attribute_names.collect do |name|
706
+ if _has_attribute?(name)
707
+ "#{name}: #{attribute_for_inspect(name)}"
708
+ end
709
+ end.compact.join(", ")
710
+ else
711
+ "not initialized"
712
+ end
713
+
456
714
  "#<#{self.class} #{inspection}>"
457
715
  end
458
716
 
459
- # Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record`
717
+ # Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
460
718
  # when pp is required.
461
719
  def pretty_print(pp)
462
720
  return super if custom_inspect_method_defined?
463
721
  pp.object_address_group(self) do
464
722
  if defined?(@attributes) && @attributes
465
- column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
466
- pp.seplist(column_names, proc { pp.text ',' }) do |column_name|
467
- column_value = read_attribute(column_name)
468
- pp.breakable ' '
723
+ attr_names = self.class.attribute_names.select { |name| _has_attribute?(name) }
724
+ pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
725
+ pp.breakable " "
469
726
  pp.group(1) do
470
- pp.text column_name
471
- pp.text ':'
727
+ pp.text attr_name
728
+ pp.text ":"
472
729
  pp.breakable
473
- pp.pp column_value
730
+ value = _read_attribute(attr_name)
731
+ value = inspection_filter.filter_param(attr_name, value) unless value.nil?
732
+ pp.pp value
474
733
  end
475
734
  end
476
735
  else
477
- pp.breakable ' '
478
- pp.text 'not initialized'
736
+ pp.breakable " "
737
+ pp.text "not initialized"
479
738
  end
480
739
  end
481
740
  end
482
741
 
483
742
  # Returns a hash of the given methods with their names as keys and returned values as values.
484
743
  def slice(*methods)
485
- Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
744
+ methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
486
745
  end
487
746
 
488
- private
489
-
490
- def set_transaction_state(state) # :nodoc:
491
- @transaction_state = state
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) }
492
750
  end
493
751
 
494
- def has_transactional_callbacks? # :nodoc:
495
- !_rollback_callbacks.empty? || !_commit_callbacks.empty?
496
- end
752
+ private
753
+ # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
754
+ # the array, and then rescues from the possible +NoMethodError+. If those elements are
755
+ # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
756
+ # which significantly impacts upon performance.
757
+ #
758
+ # So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
759
+ #
760
+ # See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
761
+ def to_ary
762
+ nil
763
+ end
497
764
 
498
- # Updates the attributes on this particular ActiveRecord object so that
499
- # if it is associated with a transaction, then the state of the AR object
500
- # will be updated to reflect the current state of the transaction
501
- #
502
- # The @transaction_state variable stores the states of the associated
503
- # transaction. This relies on the fact that a transaction can only be in
504
- # one rollback or commit (otherwise a list of states would be required)
505
- # Each AR object inside of a transaction carries that transaction's
506
- # TransactionState.
507
- #
508
- # This method checks to see if the ActiveRecord object's state reflects
509
- # the TransactionState, and rolls back or commits the ActiveRecord object
510
- # as appropriate.
511
- #
512
- # Since ActiveRecord objects can be inside multiple transactions, this
513
- # method recursively goes through the parent of the TransactionState and
514
- # checks if the ActiveRecord object reflects the state of the object.
515
- def sync_with_transaction_state
516
- update_attributes_from_transaction_state(@transaction_state, 0)
517
- end
765
+ def init_internals
766
+ @primary_key = self.class.primary_key
767
+ @readonly = false
768
+ @previously_new_record = false
769
+ @destroyed = false
770
+ @marked_for_destruction = false
771
+ @destroyed_by_association = nil
772
+ @_start_transaction_state = nil
773
+ @strict_loading = self.class.strict_loading_by_default
774
+
775
+ self.class.define_attribute_methods
776
+ end
518
777
 
519
- def update_attributes_from_transaction_state(transaction_state, depth)
520
- @reflects_state = [false] if depth == 0
778
+ def initialize_internals_callback
779
+ end
521
780
 
522
- if transaction_state && transaction_state.finalized? && !has_transactional_callbacks?
523
- unless @reflects_state[depth]
524
- restore_transaction_record_state if transaction_state.rolledback?
525
- clear_transaction_record_state
526
- @reflects_state[depth] = true
527
- end
781
+ def custom_inspect_method_defined?
782
+ self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
783
+ end
528
784
 
529
- if transaction_state.parent && !@reflects_state[depth+1]
530
- update_attributes_from_transaction_state(transaction_state.parent, depth+1)
785
+ class InspectionMask < DelegateClass(::String)
786
+ def pretty_print(pp)
787
+ pp.text __getobj__
531
788
  end
532
789
  end
533
- end
534
-
535
- # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
536
- # of the array, and then rescues from the possible NoMethodError. If those elements are
537
- # ActiveRecord::Base's, then this triggers the various method_missing's that we have,
538
- # which significantly impacts upon performance.
539
- #
540
- # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
541
- #
542
- # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
543
- def to_ary # :nodoc:
544
- nil
545
- end
546
-
547
- def init_internals
548
- @aggregation_cache = {}
549
- @association_cache = {}
550
- @readonly = false
551
- @destroyed = false
552
- @marked_for_destruction = false
553
- @destroyed_by_association = nil
554
- @new_record = true
555
- @txn = nil
556
- @_start_transaction_state = {}
557
- @transaction_state = nil
558
- end
559
-
560
- def initialize_internals_callback
561
- end
562
-
563
- # This method is needed to make protected_attributes gem easier to hook.
564
- # Remove it when we drop support to this gem.
565
- def init_attributes(attributes, options)
566
- assign_attributes(attributes)
567
- end
790
+ private_constant :InspectionMask
568
791
 
569
- def thaw
570
- if frozen?
571
- @attributes = @attributes.dup
792
+ def inspection_filter
793
+ self.class.inspection_filter
572
794
  end
573
- end
574
-
575
- def custom_inspect_method_defined?
576
- self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
577
- end
578
795
  end
579
796
  end