activerecord 4.2.11.1 → 6.0.3

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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +711 -1547
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +266 -251
  9. data/lib/active_record/association_relation.rb +20 -13
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +128 -57
  12. data/lib/active_record/associations/association_scope.rb +103 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -66
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +136 -288
  23. data/lib/active_record/associations/collection_proxy.rb +241 -147
  24. data/lib/active_record/associations/foreign_association.rb +10 -1
  25. data/lib/active_record/associations/has_many_association.rb +34 -98
  26. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  27. data/lib/active_record/associations/has_one_association.rb +61 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  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 +149 -166
  33. data/lib/active_record/associations/preloader/association.rb +90 -123
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +90 -93
  36. data/lib/active_record/associations/singular_association.rb +18 -39
  37. data/lib/active_record/associations/through_association.rb +38 -18
  38. data/lib/active_record/associations.rb +1737 -1597
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +57 -37
  48. data/lib/active_record/attribute_methods/write.rb +32 -55
  49. data/lib/active_record/attribute_methods.rb +120 -135
  50. data/lib/active_record/attributes.rb +213 -82
  51. data/lib/active_record/autosave_association.rb +97 -41
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +23 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +804 -297
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +240 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +371 -242
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +694 -256
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +473 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +507 -639
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -181
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -114
  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 +5 -1
  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 +9 -22
  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/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 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +51 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  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 +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -296
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  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 +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  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 +299 -349
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +252 -230
  130. data/lib/active_record/counter_cache.rb +70 -49
  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 -106
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  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 +227 -501
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +86 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +623 -305
  165. data/lib/active_record/model_schema.rb +313 -112
  166. data/lib/active_record/nested_attributes.rb +263 -223
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +557 -126
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +143 -44
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +331 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +430 -281
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +268 -254
  182. data/lib/active_record/relation/delegation.rb +75 -84
  183. data/lib/active_record/relation/finder_methods.rb +285 -241
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +78 -88
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +110 -119
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +603 -397
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +11 -14
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +530 -341
  201. data/lib/active_record/result.rb +79 -43
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping/default.rb +98 -83
  208. data/lib/active_record/scoping/named.rb +86 -33
  209. data/lib/active_record/scoping.rb +45 -27
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -100
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +80 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +223 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -45
  228. data/lib/active_record/type/date_time.rb +4 -49
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +23 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +11 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +42 -55
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +42 -22
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. data/lib/rails/generators/active_record.rb +7 -5
  341. metadata +168 -59
  342. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  343. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  344. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  345. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  346. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  347. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  348. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  349. data/lib/active_record/attribute.rb +0 -163
  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/mysql_adapter.rb +0 -498
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -31
  363. data/lib/active_record/type/decimal.rb +0 -64
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -59
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -40
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -110
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -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 = 4
9
- MINOR = 2
10
- TINY = 11
11
- PRE = "1"
10
+ MAJOR = 6
11
+ MINOR = 0
12
+ TINY = 3
13
+ PRE = nil
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,33 +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
- if subclass_from_attributes?(attrs)
55
- subclass = subclass_from_attributes(attrs)
55
+ if has_attribute?(inheritance_column)
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
61
+
62
+ if subclass.nil? && base_class?
63
+ subclass = subclass_from_attributes(column_defaults)
64
+ end
56
65
  end
57
66
 
58
- if subclass
59
- subclass.new(*args, &block)
67
+ if subclass && subclass != self
68
+ subclass.new(attributes, &block)
60
69
  else
61
70
  super
62
71
  end
@@ -79,20 +88,10 @@ module ActiveRecord
79
88
  :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
80
89
  end
81
90
 
82
- def symbolized_base_class
83
- ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_base_class` is deprecated and will be removed without replacement.')
84
- @symbolized_base_class ||= base_class.to_s.to_sym
85
- end
86
-
87
- def symbolized_sti_name
88
- ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_sti_name` is deprecated and will be removed without replacement.')
89
- @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
90
- end
91
-
92
91
  # Returns the class descending directly from ActiveRecord::Base, or
93
92
  # an abstract class, if any, in the inheritance hierarchy.
94
93
  #
95
- # If A extends AR::Base, A.base_class will return A. If B descends from A
94
+ # If A extends ActiveRecord::Base, A.base_class will return A. If B descends from A
96
95
  # through some arbitrarily deep hierarchy, B.base_class will return A.
97
96
  #
98
97
  # If B < A and C < B and if A is an abstract_class then both B.base_class
@@ -109,21 +108,53 @@ module ActiveRecord
109
108
  end
110
109
  end
111
110
 
112
- # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
113
- # If you are using inheritance with ActiveRecord and don't want child classes
114
- # to utilize the implied STI table name of the parent class, this will need to be true.
115
- # 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:
125
+ #
126
+ # Shape = Class.new(ActiveRecord::Base)
127
+ # Polygon = Class.new(Shape)
128
+ # Square = Class.new(Polygon)
116
129
  #
117
- # class SuperClass < ActiveRecord::Base
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
118
141
  # self.abstract_class = true
119
142
  # end
120
- # class Child < SuperClass
121
- # self.table_name = 'the_table_i_really_want'
122
- # end
123
- #
143
+ # Polygon = Class.new(Shape)
144
+ # Square = Class.new(Polygon)
124
145
  #
125
- # <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">
126
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.
127
158
  attr_accessor :abstract_class
128
159
 
129
160
  # Returns whether this class is an abstract class or not.
@@ -135,89 +166,102 @@ module ActiveRecord
135
166
  store_full_sti_class ? name : name.demodulize
136
167
  end
137
168
 
138
- protected
169
+ def polymorphic_name
170
+ base_class.name
171
+ end
139
172
 
140
- # Returns the class type of the record using the current module as a prefix. So descendants of
141
- # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
142
- def compute_type(type_name)
143
- if type_name.match(/^::/)
144
- # If the type is prefixed with a scope operator then we assume that
145
- # the type_name is an absolute reference.
146
- ActiveSupport::Dependencies.constantize(type_name)
147
- else
148
- # Build a list of candidates to search for
149
- candidates = []
150
- name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
151
- candidates << type_name
152
-
153
- candidates.each do |candidate|
154
- constant = ActiveSupport::Dependencies.safe_constantize(candidate)
155
- return constant if candidate == constant.to_s
156
- end
173
+ def inherited(subclass)
174
+ subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
175
+ super
176
+ end
157
177
 
158
- raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
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
191
+
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
204
+
205
+ raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
206
+ end
159
207
  end
160
- end
161
208
 
162
209
  private
163
-
164
- # Called by +instantiate+ to decide which class to use for a new
165
- # record instance. For single-table inheritance, we check the record
166
- # for a +type+ column and return the corresponding class.
167
- def discriminate_class_for_record(record)
168
- if using_single_table_inheritance?(record)
169
- find_sti_class(record[inheritance_column])
170
- else
171
- 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
172
219
  end
173
- end
174
220
 
175
- def using_single_table_inheritance?(record)
176
- record[inheritance_column].present? && columns_hash.include?(inheritance_column)
177
- end
178
-
179
- def find_sti_class(type_name)
180
- if store_full_sti_class
181
- ActiveSupport::Dependencies.constantize(type_name)
182
- else
183
- compute_type(type_name)
221
+ def using_single_table_inheritance?(record)
222
+ record[inheritance_column].present? && has_attribute?(inheritance_column)
184
223
  end
185
- rescue NameError
186
- raise SubclassNotFound,
187
- "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
188
- "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
189
- "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
190
- "or overwrite #{name}.inheritance_column to use another column for that information."
191
- end
192
-
193
- def type_condition(table = arel_table)
194
- sti_column = table[inheritance_column]
195
- sti_names = ([self] + descendants).map { |model| model.sti_name }
196
224
 
197
- sti_column.in(sti_names)
198
- end
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."
239
+ end
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
244
+ end
199
245
 
200
- # Detect the subclass from the inheritance column of attrs. If the inheritance column value
201
- # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
202
- # If this is a StrongParameters hash, and access to inheritance_column is not permitted,
203
- # this will ignore the inheritance column and return nil
204
- def subclass_from_attributes?(attrs)
205
- columns_hash.include?(inheritance_column) && attrs.is_a?(Hash)
206
- end
246
+ def type_condition(table = arel_table)
247
+ sti_column = arel_attribute(inheritance_column, table)
248
+ sti_names = ([self] + descendants).map(&:sti_name)
207
249
 
208
- def subclass_from_attributes(attrs)
209
- subclass_name = attrs.with_indifferent_access[inheritance_column]
250
+ predicate_builder.build(sti_column, sti_names)
251
+ end
210
252
 
211
- if subclass_name.present? && subclass_name != self.name
212
- subclass = subclass_name.safe_constantize
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]
213
259
 
214
- unless descendants.include?(subclass)
215
- raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
260
+ if subclass_name.present?
261
+ find_sti_class(subclass_name)
262
+ end
216
263
  end
217
-
218
- subclass
219
264
  end
220
- end
221
265
  end
222
266
 
223
267
  def initialize_dup(other)
@@ -226,22 +270,21 @@ module ActiveRecord
226
270
  end
227
271
 
228
272
  private
273
+ def initialize_internals_callback
274
+ super
275
+ ensure_proper_type
276
+ end
229
277
 
230
- def initialize_internals_callback
231
- super
232
- ensure_proper_type
233
- end
234
-
235
- # Sets the attribute used for single table inheritance to this class name if this is not the
236
- # ActiveRecord::Base descendant.
237
- # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
238
- # do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
239
- # No such attribute would be set for objects of the Message class in that example.
240
- def ensure_proper_type
241
- klass = self.class
242
- if klass.finder_needs_type_condition?
243
- 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
244
288
  end
245
- end
246
289
  end
247
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
+ quote_columns(columns).join(",")
172
+ end
173
+
174
+ def quote_columns(columns)
175
+ columns.map(&connection.method(:quote_column_name))
176
+ end
177
+ end
178
+ end
179
+ end