activerecord 5.0.7.2 → 6.0.6.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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +844 -1944
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +18 -14
  10. data/lib/active_record/associations/alias_tracker.rb +24 -34
  11. data/lib/active_record/associations/association.rb +113 -55
  12. data/lib/active_record/associations/association_scope.rb +102 -96
  13. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +18 -25
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  19. data/lib/active_record/associations/builder/has_many.rb +4 -0
  20. data/lib/active_record/associations/builder/has_one.rb +37 -1
  21. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  22. data/lib/active_record/associations/collection_association.rb +93 -254
  23. data/lib/active_record/associations/collection_proxy.rb +159 -122
  24. data/lib/active_record/associations/foreign_association.rb +9 -0
  25. data/lib/active_record/associations/has_many_association.rb +23 -30
  26. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  27. data/lib/active_record/associations/has_one_association.rb +59 -54
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +152 -177
  33. data/lib/active_record/associations/preloader/association.rb +101 -97
  34. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  35. data/lib/active_record/associations/preloader.rb +94 -103
  36. data/lib/active_record/associations/singular_association.rb +12 -45
  37. data/lib/active_record/associations/through_association.rb +27 -15
  38. data/lib/active_record/associations.rb +1603 -1592
  39. data/lib/active_record/attribute_assignment.rb +54 -61
  40. data/lib/active_record/attribute_decorators.rb +38 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  43. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  44. data/lib/active_record/attribute_methods/query.rb +4 -3
  45. data/lib/active_record/attribute_methods/read.rb +20 -49
  46. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  48. data/lib/active_record/attribute_methods/write.rb +34 -33
  49. data/lib/active_record/attribute_methods.rb +66 -106
  50. data/lib/active_record/attributes.rb +38 -25
  51. data/lib/active_record/autosave_association.rb +58 -39
  52. data/lib/active_record/base.rb +27 -24
  53. data/lib/active_record/callbacks.rb +64 -35
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +34 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
  69. data/lib/active_record/connection_adapters/column.rb +41 -13
  70. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  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 +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
  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 +19 -18
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  99. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  117. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +261 -267
  127. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  128. data/lib/active_record/connection_handling.rb +143 -40
  129. data/lib/active_record/core.rb +207 -160
  130. data/lib/active_record/counter_cache.rb +60 -28
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -87
  137. data/lib/active_record/enum.rb +67 -23
  138. data/lib/active_record/errors.rb +114 -18
  139. data/lib/active_record/explain.rb +4 -4
  140. data/lib/active_record/explain_registry.rb +3 -1
  141. data/lib/active_record/explain_subscriber.rb +9 -4
  142. data/lib/active_record/fixture_set/file.rb +13 -8
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +194 -504
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +150 -99
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +116 -25
  152. data/lib/active_record/internal_metadata.rb +16 -19
  153. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  154. data/lib/active_record/locking/optimistic.rb +85 -86
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +48 -29
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  159. data/lib/active_record/middleware/database_selector.rb +74 -0
  160. data/lib/active_record/migration/command_recorder.rb +134 -100
  161. data/lib/active_record/migration/compatibility.rb +174 -56
  162. data/lib/active_record/migration/join_table.rb +8 -7
  163. data/lib/active_record/migration.rb +369 -302
  164. data/lib/active_record/model_schema.rb +160 -127
  165. data/lib/active_record/nested_attributes.rb +213 -202
  166. data/lib/active_record/no_touching.rb +12 -3
  167. data/lib/active_record/null_relation.rb +12 -34
  168. data/lib/active_record/persistence.rb +446 -77
  169. data/lib/active_record/query_cache.rb +13 -12
  170. data/lib/active_record/querying.rb +37 -24
  171. data/lib/active_record/railtie.rb +128 -36
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +312 -177
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +214 -254
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  179. data/lib/active_record/relation/batches.rb +98 -52
  180. data/lib/active_record/relation/calculations.rb +212 -173
  181. data/lib/active_record/relation/delegation.rb +73 -69
  182. data/lib/active_record/relation/finder_methods.rb +207 -247
  183. data/lib/active_record/relation/from_clause.rb +6 -8
  184. data/lib/active_record/relation/merger.rb +82 -61
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  192. data/lib/active_record/relation/predicate_builder.rb +83 -105
  193. data/lib/active_record/relation/query_attribute.rb +33 -2
  194. data/lib/active_record/relation/query_methods.rb +488 -332
  195. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  196. data/lib/active_record/relation/spawn_methods.rb +8 -8
  197. data/lib/active_record/relation/where_clause.rb +111 -96
  198. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  199. data/lib/active_record/relation.rb +443 -318
  200. data/lib/active_record/result.rb +69 -40
  201. data/lib/active_record/runtime_registry.rb +5 -3
  202. data/lib/active_record/sanitization.rb +83 -99
  203. data/lib/active_record/schema.rb +7 -14
  204. data/lib/active_record/schema_dumper.rb +71 -69
  205. data/lib/active_record/schema_migration.rb +16 -6
  206. data/lib/active_record/scoping/default.rb +92 -95
  207. data/lib/active_record/scoping/named.rb +51 -26
  208. data/lib/active_record/scoping.rb +20 -20
  209. data/lib/active_record/secure_token.rb +4 -2
  210. data/lib/active_record/serialization.rb +2 -0
  211. data/lib/active_record/statement_cache.rb +63 -28
  212. data/lib/active_record/store.rb +121 -41
  213. data/lib/active_record/suppressor.rb +6 -3
  214. data/lib/active_record/table_metadata.rb +39 -18
  215. data/lib/active_record/tasks/database_tasks.rb +271 -81
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +243 -0
  221. data/lib/active_record/timestamp.rb +70 -36
  222. data/lib/active_record/touch_later.rb +8 -6
  223. data/lib/active_record/transactions.rb +141 -157
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  226. data/lib/active_record/type/date.rb +2 -0
  227. data/lib/active_record/type/date_time.rb +2 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  230. data/lib/active_record/type/internal/timezone.rb +2 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +16 -9
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +12 -1
  235. data/lib/active_record/type/type_map.rb +14 -17
  236. data/lib/active_record/type/unsigned_integer.rb +16 -0
  237. data/lib/active_record/type.rb +23 -18
  238. data/lib/active_record/type_caster/connection.rb +17 -12
  239. data/lib/active_record/type_caster/map.rb +5 -4
  240. data/lib/active_record/type_caster.rb +4 -2
  241. data/lib/active_record/validations/absence.rb +2 -0
  242. data/lib/active_record/validations/associated.rb +3 -2
  243. data/lib/active_record/validations/length.rb +2 -0
  244. data/lib/active_record/validations/presence.rb +4 -2
  245. data/lib/active_record/validations/uniqueness.rb +29 -42
  246. data/lib/active_record/validations.rb +7 -5
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +37 -22
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +256 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +203 -0
  315. data/lib/arel/visitors/dot.rb +296 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +156 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +158 -0
  321. data/lib/arel/visitors/oracle12.rb +65 -0
  322. data/lib/arel/visitors/postgresql.rb +109 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +888 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors/where_sql.rb +22 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +62 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 -3
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record.rb +7 -5
  338. metadata +138 -52
  339. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  340. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  341. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  343. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  344. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  345. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  346. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  349. data/lib/active_record/attribute_set/builder.rb +0 -132
  350. data/lib/active_record/attribute_set.rb +0 -110
  351. data/lib/active_record/collection_cache_key.rb +0 -50
  352. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  353. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  354. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  355. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  356. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  357. data/lib/active_record/type/internal/abstract_json.rb +0 -33
  358. /data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  359. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # Returns the version of the currently loaded Active Record as a <tt>Gem::Version</tt>
3
5
  def self.gem_version
@@ -5,10 +7,10 @@ module ActiveRecord
5
7
  end
6
8
 
7
9
  module VERSION
8
- MAJOR = 5
10
+ MAJOR = 6
9
11
  MINOR = 0
10
- TINY = 7
11
- PRE = "2"
12
+ TINY = 6
13
+ PRE = "1"
12
14
 
13
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
16
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
2
4
 
3
5
  module ActiveRecord
4
6
  # == Single table inheritance
@@ -19,7 +21,7 @@ module ActiveRecord
19
21
  # Be aware that because the type column is an attribute on the record every new
20
22
  # subclass will instantly be marked as dirty and the type column will be included
21
23
  # in the list of changed attributes on the record. This is different from non
22
- # STI classes:
24
+ # Single Table Inheritance(STI) classes:
23
25
  #
24
26
  # Company.new.changed? # => false
25
27
  # Firm.new.changed? # => true
@@ -30,37 +32,40 @@ module ActiveRecord
30
32
  # for differentiating between them or reloading the right type with find.
31
33
  #
32
34
  # Note, all the attributes for all the cases are kept in the same table. Read more:
33
- # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
35
+ # https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
34
36
  #
35
37
  module Inheritance
36
38
  extend ActiveSupport::Concern
37
39
 
38
40
  included do
39
41
  # Determines whether to store the full constant name including namespace when using STI.
40
- class_attribute :store_full_sti_class, instance_writer: false
41
- self.store_full_sti_class = true
42
+ # This is true, by default.
43
+ class_attribute :store_full_sti_class, instance_writer: false, default: true
42
44
  end
43
45
 
44
46
  module ClassMethods
45
47
  # Determines if one of the attributes passed in is the inheritance column,
46
48
  # and if the inheritance column is attr accessible, it initializes an
47
49
  # instance of the given subclass instead of the base class.
48
- def new(*args, &block)
50
+ def new(attributes = nil, &block)
49
51
  if abstract_class? || self == Base
50
52
  raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
51
53
  end
52
54
 
53
- attrs = args.first
54
55
  if has_attribute?(inheritance_column)
55
- subclass = subclass_from_attributes(attrs)
56
+ subclass = subclass_from_attributes(attributes)
57
+
58
+ if subclass.nil? && scope_attributes = current_scope&.scope_for_create
59
+ subclass = subclass_from_attributes(scope_attributes)
60
+ end
56
61
 
57
- if subclass.nil? && base_class == self
62
+ if subclass.nil? && base_class?
58
63
  subclass = subclass_from_attributes(column_defaults)
59
64
  end
60
65
  end
61
66
 
62
67
  if subclass && subclass != self
63
- subclass.new(*args, &block)
68
+ subclass.new(attributes, &block)
64
69
  else
65
70
  super
66
71
  end
@@ -103,21 +108,53 @@ module ActiveRecord
103
108
  end
104
109
  end
105
110
 
106
- # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
107
- # If you are using inheritance with ActiveRecord and don't want child classes
108
- # to utilize the implied STI table name of the parent class, this will need to be true.
109
- # For example, given the following:
111
+ # Returns whether the class is a base class.
112
+ # See #base_class for more information.
113
+ def base_class?
114
+ base_class == self
115
+ end
116
+
117
+ # Set this to +true+ if this is an abstract class (see
118
+ # <tt>abstract_class?</tt>).
119
+ # If you are using inheritance with Active Record and don't want a class
120
+ # to be considered as part of the STI hierarchy, you must set this to
121
+ # true.
122
+ # +ApplicationRecord+, for example, is generated as an abstract class.
123
+ #
124
+ # Consider the following default behaviour:
110
125
  #
111
- # class SuperClass < ActiveRecord::Base
126
+ # Shape = Class.new(ActiveRecord::Base)
127
+ # Polygon = Class.new(Shape)
128
+ # Square = Class.new(Polygon)
129
+ #
130
+ # Shape.table_name # => "shapes"
131
+ # Polygon.table_name # => "shapes"
132
+ # Square.table_name # => "shapes"
133
+ # Shape.create! # => #<Shape id: 1, type: nil>
134
+ # Polygon.create! # => #<Polygon id: 2, type: "Polygon">
135
+ # Square.create! # => #<Square id: 3, type: "Square">
136
+ #
137
+ # However, when using <tt>abstract_class</tt>, +Shape+ is omitted from
138
+ # the hierarchy:
139
+ #
140
+ # class Shape < ActiveRecord::Base
112
141
  # self.abstract_class = true
113
142
  # end
114
- # class Child < SuperClass
115
- # self.table_name = 'the_table_i_really_want'
116
- # end
117
- #
143
+ # Polygon = Class.new(Shape)
144
+ # Square = Class.new(Polygon)
118
145
  #
119
- # <tt>self.abstract_class = true</tt> is required to make <tt>Child<.find,.create, or any Arel method></tt> use <tt>the_table_i_really_want</tt> instead of a table called <tt>super_classes</tt>
146
+ # Shape.table_name # => nil
147
+ # Polygon.table_name # => "polygons"
148
+ # Square.table_name # => "polygons"
149
+ # Shape.create! # => NotImplementedError: Shape is an abstract class and cannot be instantiated.
150
+ # Polygon.create! # => #<Polygon id: 1, type: nil>
151
+ # Square.create! # => #<Square id: 2, type: "Square">
120
152
  #
153
+ # Note that in the above example, to disallow the creation of a plain
154
+ # +Polygon+, you should use <tt>validates :type, presence: true</tt>,
155
+ # instead of setting it as an abstract class. This way, +Polygon+ will
156
+ # stay in the hierarchy, and Active Record will continue to correctly
157
+ # derive the table name.
121
158
  attr_accessor :abstract_class
122
159
 
123
160
  # Returns whether this class is an abstract class or not.
@@ -129,87 +166,102 @@ module ActiveRecord
129
166
  store_full_sti_class ? name : name.demodulize
130
167
  end
131
168
 
169
+ def polymorphic_name
170
+ base_class.name
171
+ end
172
+
173
+ def inherited(subclass)
174
+ subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
175
+ super
176
+ end
177
+
132
178
  protected
179
+ # Returns the class type of the record using the current module as a prefix. So descendants of
180
+ # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
181
+ def compute_type(type_name)
182
+ if type_name.start_with?("::")
183
+ # If the type is prefixed with a scope operator then we assume that
184
+ # the type_name is an absolute reference.
185
+ ActiveSupport::Dependencies.constantize(type_name)
186
+ else
187
+ type_candidate = @_type_candidates_cache[type_name]
188
+ if type_candidate && type_constant = ActiveSupport::Dependencies.safe_constantize(type_candidate)
189
+ return type_constant
190
+ end
133
191
 
134
- # Returns the class type of the record using the current module as a prefix. So descendants of
135
- # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
136
- def compute_type(type_name)
137
- if type_name.match(/^::/)
138
- # If the type is prefixed with a scope operator then we assume that
139
- # the type_name is an absolute reference.
140
- ActiveSupport::Dependencies.constantize(type_name)
141
- else
142
- # Build a list of candidates to search for
143
- candidates = []
144
- name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
145
- candidates << type_name
146
-
147
- candidates.each do |candidate|
148
- constant = ActiveSupport::Dependencies.safe_constantize(candidate)
149
- return constant if candidate == constant.to_s
150
- end
192
+ # Build a list of candidates to search for
193
+ candidates = []
194
+ name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
195
+ candidates << type_name
196
+
197
+ candidates.each do |candidate|
198
+ constant = ActiveSupport::Dependencies.safe_constantize(candidate)
199
+ if candidate == constant.to_s
200
+ @_type_candidates_cache[type_name] = candidate
201
+ return constant
202
+ end
203
+ end
151
204
 
152
- raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
205
+ raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
206
+ end
153
207
  end
154
- end
155
208
 
156
209
  private
157
-
158
- # Called by +instantiate+ to decide which class to use for a new
159
- # record instance. For single-table inheritance, we check the record
160
- # for a +type+ column and return the corresponding class.
161
- def discriminate_class_for_record(record)
162
- if using_single_table_inheritance?(record)
163
- find_sti_class(record[inheritance_column])
164
- else
165
- super
210
+ # Called by +instantiate+ to decide which class to use for a new
211
+ # record instance. For single-table inheritance, we check the record
212
+ # for a +type+ column and return the corresponding class.
213
+ def discriminate_class_for_record(record)
214
+ if using_single_table_inheritance?(record)
215
+ find_sti_class(record[inheritance_column])
216
+ else
217
+ super
218
+ end
166
219
  end
167
- end
168
220
 
169
- def using_single_table_inheritance?(record)
170
- record[inheritance_column].present? && has_attribute?(inheritance_column)
171
- end
221
+ def using_single_table_inheritance?(record)
222
+ record[inheritance_column].present? && has_attribute?(inheritance_column)
223
+ end
172
224
 
173
- def find_sti_class(type_name)
174
- type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
175
- subclass = begin
176
- if store_full_sti_class
177
- ActiveSupport::Dependencies.constantize(type_name)
178
- else
179
- compute_type(type_name)
225
+ def find_sti_class(type_name)
226
+ type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
227
+ subclass = begin
228
+ if store_full_sti_class
229
+ ActiveSupport::Dependencies.constantize(type_name)
230
+ else
231
+ compute_type(type_name)
232
+ end
233
+ rescue NameError
234
+ raise SubclassNotFound,
235
+ "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
236
+ "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
237
+ "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
238
+ "or overwrite #{name}.inheritance_column to use another column for that information."
180
239
  end
181
- rescue NameError
182
- raise SubclassNotFound,
183
- "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
184
- "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
185
- "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
186
- "or overwrite #{name}.inheritance_column to use another column for that information."
187
- end
188
- unless subclass == self || descendants.include?(subclass)
189
- raise SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
240
+ unless subclass == self || descendants.include?(subclass)
241
+ raise SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
242
+ end
243
+ subclass
190
244
  end
191
- subclass
192
- end
193
245
 
194
- def type_condition(table = arel_table)
195
- sti_column = arel_attribute(inheritance_column, table)
196
- sti_names = ([self] + descendants).map(&:sti_name)
246
+ def type_condition(table = arel_table)
247
+ sti_column = arel_attribute(inheritance_column, table)
248
+ sti_names = ([self] + descendants).map(&:sti_name)
197
249
 
198
- sti_column.in(sti_names)
199
- end
250
+ predicate_builder.build(sti_column, sti_names)
251
+ end
200
252
 
201
- # Detect the subclass from the inheritance column of attrs. If the inheritance column value
202
- # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
203
- def subclass_from_attributes(attrs)
204
- attrs = attrs.to_h if attrs.respond_to?(:permitted?)
205
- if attrs.is_a?(Hash)
206
- subclass_name = attrs.with_indifferent_access[inheritance_column]
253
+ # Detect the subclass from the inheritance column of attrs. If the inheritance column value
254
+ # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
255
+ def subclass_from_attributes(attrs)
256
+ attrs = attrs.to_h if attrs.respond_to?(:permitted?)
257
+ if attrs.is_a?(Hash)
258
+ subclass_name = attrs[inheritance_column] || attrs[inheritance_column.to_sym]
207
259
 
208
- if subclass_name.present?
209
- find_sti_class(subclass_name)
260
+ if subclass_name.present?
261
+ find_sti_class(subclass_name)
262
+ end
210
263
  end
211
264
  end
212
- end
213
265
  end
214
266
 
215
267
  def initialize_dup(other)
@@ -218,22 +270,21 @@ module ActiveRecord
218
270
  end
219
271
 
220
272
  private
273
+ def initialize_internals_callback
274
+ super
275
+ ensure_proper_type
276
+ end
221
277
 
222
- def initialize_internals_callback
223
- super
224
- ensure_proper_type
225
- end
226
-
227
- # Sets the attribute used for single table inheritance to this class name if this is not the
228
- # ActiveRecord::Base descendant.
229
- # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
230
- # do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
231
- # No such attribute would be set for objects of the Message class in that example.
232
- def ensure_proper_type
233
- klass = self.class
234
- if klass.finder_needs_type_condition?
235
- write_attribute(klass.inheritance_column, klass.sti_name)
278
+ # Sets the attribute used for single table inheritance to this class name if this is not the
279
+ # ActiveRecord::Base descendant.
280
+ # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
281
+ # do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
282
+ # No such attribute would be set for objects of the Message class in that example.
283
+ def ensure_proper_type
284
+ klass = self.class
285
+ if klass.finder_needs_type_condition?
286
+ _write_attribute(klass.inheritance_column, klass.sti_name)
287
+ end
236
288
  end
237
- end
238
289
  end
239
290
  end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class InsertAll # :nodoc:
5
+ attr_reader :model, :connection, :inserts, :keys
6
+ attr_reader :on_duplicate, :returning, :unique_by
7
+
8
+ def initialize(model, inserts, on_duplicate:, returning: nil, unique_by: nil)
9
+ raise ArgumentError, "Empty list of attributes passed" if inserts.blank?
10
+
11
+ @model, @connection, @inserts, @keys = model, model.connection, inserts, inserts.first.keys.map(&:to_s).to_set
12
+ @on_duplicate, @returning, @unique_by = on_duplicate, returning, unique_by
13
+
14
+ @returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
15
+ @returning = false if @returning == []
16
+
17
+ @unique_by = find_unique_index_for(unique_by) if unique_by
18
+ @on_duplicate = :skip if @on_duplicate == :update && updatable_columns.empty?
19
+
20
+ ensure_valid_options_for_connection!
21
+ end
22
+
23
+ def execute
24
+ message = +"#{model} "
25
+ message << "Bulk " if inserts.many?
26
+ message << (on_duplicate == :update ? "Upsert" : "Insert")
27
+ connection.exec_insert_all to_sql, message
28
+ end
29
+
30
+ def updatable_columns
31
+ keys - readonly_columns - unique_by_columns
32
+ end
33
+
34
+ def primary_keys
35
+ Array(model.primary_key)
36
+ end
37
+
38
+
39
+ def skip_duplicates?
40
+ on_duplicate == :skip
41
+ end
42
+
43
+ def update_duplicates?
44
+ on_duplicate == :update
45
+ end
46
+
47
+ def map_key_with_value
48
+ inserts.map do |attributes|
49
+ attributes = attributes.stringify_keys
50
+ verify_attributes(attributes)
51
+
52
+ keys.map do |key|
53
+ yield key, attributes[key]
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+ def find_unique_index_for(unique_by)
60
+ match = Array(unique_by).map(&:to_s)
61
+
62
+ if index = unique_indexes.find { |i| match.include?(i.name) || i.columns == match }
63
+ index
64
+ else
65
+ raise ArgumentError, "No unique index found for #{unique_by}"
66
+ end
67
+ end
68
+
69
+ def unique_indexes
70
+ connection.schema_cache.indexes(model.table_name).select(&:unique)
71
+ end
72
+
73
+
74
+ def ensure_valid_options_for_connection!
75
+ if returning && !connection.supports_insert_returning?
76
+ raise ArgumentError, "#{connection.class} does not support :returning"
77
+ end
78
+
79
+ if skip_duplicates? && !connection.supports_insert_on_duplicate_skip?
80
+ raise ArgumentError, "#{connection.class} does not support skipping duplicates"
81
+ end
82
+
83
+ if update_duplicates? && !connection.supports_insert_on_duplicate_update?
84
+ raise ArgumentError, "#{connection.class} does not support upsert"
85
+ end
86
+
87
+ if unique_by && !connection.supports_insert_conflict_target?
88
+ raise ArgumentError, "#{connection.class} does not support :unique_by"
89
+ end
90
+ end
91
+
92
+
93
+ def to_sql
94
+ connection.build_insert_sql(ActiveRecord::InsertAll::Builder.new(self))
95
+ end
96
+
97
+
98
+ def readonly_columns
99
+ primary_keys + model.readonly_attributes.to_a
100
+ end
101
+
102
+ def unique_by_columns
103
+ Array(unique_by&.columns)
104
+ end
105
+
106
+
107
+ def verify_attributes(attributes)
108
+ if keys != attributes.keys.to_set
109
+ raise ArgumentError, "All objects being inserted must have the same keys"
110
+ end
111
+ end
112
+
113
+ class Builder # :nodoc:
114
+ attr_reader :model
115
+
116
+ delegate :skip_duplicates?, :update_duplicates?, :keys, to: :insert_all
117
+
118
+ def initialize(insert_all)
119
+ @insert_all, @model, @connection = insert_all, insert_all.model, insert_all.connection
120
+ end
121
+
122
+ def into
123
+ "INTO #{model.quoted_table_name} (#{columns_list})"
124
+ end
125
+
126
+ def values_list
127
+ types = extract_types_from_columns_on(model.table_name, keys: keys)
128
+
129
+ values_list = insert_all.map_key_with_value do |key, value|
130
+ connection.with_yaml_fallback(types[key].serialize(value))
131
+ end
132
+
133
+ connection.visitor.compile(Arel::Nodes::ValuesList.new(values_list))
134
+ end
135
+
136
+ def returning
137
+ format_columns(insert_all.returning) if insert_all.returning
138
+ end
139
+
140
+ def conflict_target
141
+ if index = insert_all.unique_by
142
+ sql = +"(#{format_columns(index.columns)})"
143
+ sql << " WHERE #{index.where}" if index.where
144
+ sql
145
+ elsif update_duplicates?
146
+ "(#{format_columns(insert_all.primary_keys)})"
147
+ end
148
+ end
149
+
150
+ def updatable_columns
151
+ quote_columns(insert_all.updatable_columns)
152
+ end
153
+
154
+ private
155
+ attr_reader :connection, :insert_all
156
+
157
+ def columns_list
158
+ format_columns(insert_all.keys)
159
+ end
160
+
161
+ def extract_types_from_columns_on(table_name, keys:)
162
+ columns = connection.schema_cache.columns_hash(table_name)
163
+
164
+ unknown_column = (keys - columns.keys).first
165
+ raise UnknownAttributeError.new(model.new, unknown_column) if unknown_column
166
+
167
+ keys.index_with { |key| model.type_for_attribute(key) }
168
+ end
169
+
170
+ def format_columns(columns)
171
+ columns.respond_to?(:map) ? quote_columns(columns).join(",") : columns
172
+ end
173
+
174
+ def quote_columns(columns)
175
+ columns.map(&connection.method(:quote_column_name))
176
+ end
177
+ end
178
+ end
179
+ end