activerecord 4.2.11.2 → 6.0.0

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 (372) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +613 -1638
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +131 -287
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  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 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -243
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -635
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  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 +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -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 -180
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -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 +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  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 +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -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 +118 -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 +103 -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 +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  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 +23 -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 +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -112
  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 +87 -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.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +621 -303
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +312 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  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 +328 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  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.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  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 +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -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.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -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.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -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. metadata +164 -59
  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_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -31
  362. data/lib/active_record/type/decimal.rb +0 -64
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -59
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,19 +1,20 @@
1
- require 'active_record/associations/join_dependency/join_part'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/associations/join_dependency/join_part"
4
+ require "active_support/core_ext/array/extract"
2
5
 
3
6
  module ActiveRecord
4
7
  module Associations
5
8
  class JoinDependency # :nodoc:
6
9
  class JoinAssociation < JoinPart # :nodoc:
7
- # The reflection of the association represented
8
- attr_reader :reflection
9
-
10
- attr_accessor :tables
10
+ attr_reader :reflection, :tables
11
+ attr_accessor :table
11
12
 
12
13
  def initialize(reflection, children)
13
14
  super(reflection.klass, children)
14
15
 
15
- @reflection = reflection
16
- @tables = nil
16
+ @reflection = reflection
17
+ @tables = nil
17
18
  end
18
19
 
19
20
  def match?(other)
@@ -21,107 +22,58 @@ module ActiveRecord
21
22
  super && reflection == other.reflection
22
23
  end
23
24
 
24
- JoinInformation = Struct.new :joins, :binds
25
-
26
- def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain)
27
- joins = []
28
- bind_values = []
29
- tables = tables.reverse
30
-
31
- scope_chain_index = 0
32
- scope_chain = scope_chain.reverse
25
+ def join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
26
+ joins = []
33
27
 
34
28
  # The chain starts with the target table, but we want to end with it here (makes
35
29
  # more sense in this context), so we reverse
36
- chain.reverse_each do |reflection|
37
- table = tables.shift
30
+ reflection.chain.reverse_each.with_index(1) do |reflection, i|
31
+ table = tables[-i]
38
32
  klass = reflection.klass
39
33
 
40
- join_keys = reflection.join_keys(klass)
41
- key = join_keys.key
42
- foreign_key = join_keys.foreign_key
34
+ join_scope = reflection.join_scope(table, foreign_table, foreign_klass)
43
35
 
44
- constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
45
-
46
- scope_chain_items = scope_chain[scope_chain_index].map do |item|
47
- if item.is_a?(Relation)
48
- item
49
- else
50
- ActiveRecord::Relation.create(klass, table).instance_exec(node, &item)
51
- end
52
- end
53
- scope_chain_index += 1
54
-
55
- klass_scope =
56
- if klass.current_scope && klass.current_scope.values.blank?
57
- klass.unscoped
58
- else
59
- klass.send(:build_default_scope, ActiveRecord::Relation.create(klass, table))
60
- end
61
- scope_chain_items.concat [klass_scope].compact
62
-
63
- rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
64
- left.merge right
65
- end
36
+ arel = join_scope.arel(alias_tracker.aliases)
37
+ nodes = arel.constraints.first
66
38
 
67
- if rel && !rel.arel.constraints.empty?
68
- bind_values.concat rel.bind_values
69
- constraint = constraint.and rel.arel.constraints
39
+ others = nodes.children.extract! do |node|
40
+ Arel.fetch_attribute(node) { |attr| attr.relation.name != table.name }
70
41
  end
71
42
 
72
- if reflection.type
73
- value = foreign_klass.base_class.name
74
- column = klass.columns_hash[reflection.type.to_s]
43
+ joins << table.create_join(table, table.create_on(nodes), join_type)
75
44
 
76
- substitute = klass.connection.substitute_at(column)
77
- bind_values.push [column, value]
78
- constraint = constraint.and table[reflection.type].eq substitute
45
+ unless others.empty?
46
+ joins.concat arel.join_sources
47
+ append_constraints(joins.last, others)
79
48
  end
80
49
 
81
- joins << table.create_join(table, table.create_on(constraint), join_type)
82
-
83
50
  # The current table in this iteration becomes the foreign table in the next
84
51
  foreign_table, foreign_klass = table, klass
85
52
  end
86
53
 
87
- JoinInformation.new joins, bind_values
54
+ joins
88
55
  end
89
56
 
90
- # Builds equality condition.
91
- #
92
- # Example:
93
- #
94
- # class Physician < ActiveRecord::Base
95
- # has_many :appointments
96
- # end
97
- #
98
- # If I execute `Physician.joins(:appointments).to_a` then
99
- # klass # => Physician
100
- # table # => #<Arel::Table @name="appointments" ...>
101
- # key # => physician_id
102
- # foreign_table # => #<Arel::Table @name="physicians" ...>
103
- # foreign_key # => id
104
- #
105
- def build_constraint(klass, table, key, foreign_table, foreign_key)
106
- constraint = table[key].eq(foreign_table[foreign_key])
107
-
108
- if klass.finder_needs_type_condition?
109
- constraint = table.create_and([
110
- constraint,
111
- klass.send(:type_condition, table)
112
- ])
113
- end
114
-
115
- constraint
57
+ def tables=(tables)
58
+ @tables = tables
59
+ @table = tables.first
116
60
  end
117
61
 
118
- def table
119
- tables.first
120
- end
62
+ def readonly?
63
+ return @readonly if defined?(@readonly)
121
64
 
122
- def aliased_table_name
123
- table.table_alias || table.name
65
+ @readonly = reflection.scope && reflection.scope_for(base_klass.unscoped).readonly_value
124
66
  end
67
+
68
+ private
69
+ def append_constraints(join, constraints)
70
+ if join.is_a?(Arel::Nodes::StringJoin)
71
+ join_string = table.create_and(constraints.unshift(join.left))
72
+ join.left = Arel.sql(base_klass.connection.visitor.compile(join_string))
73
+ else
74
+ join.right.expr.children.concat(constraints)
75
+ end
76
+ end
125
77
  end
126
78
  end
127
79
  end
@@ -1,20 +1,21 @@
1
- require 'active_record/associations/join_dependency/join_part'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/associations/join_dependency/join_part"
2
4
 
3
5
  module ActiveRecord
4
6
  module Associations
5
7
  class JoinDependency # :nodoc:
6
8
  class JoinBase < JoinPart # :nodoc:
7
- def match?(other)
8
- return true if self == other
9
- super && base_klass == other.base_klass
10
- end
9
+ attr_reader :table
11
10
 
12
- def table
13
- base_klass.arel_table
11
+ def initialize(base_klass, table, children)
12
+ super(base_klass, children)
13
+ @table = table
14
14
  end
15
15
 
16
- def aliased_table_name
17
- base_klass.table_name
16
+ def match?(other)
17
+ return true if self == other
18
+ super && base_klass == other.base_klass
18
19
  end
19
20
  end
20
21
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  class JoinDependency # :nodoc:
@@ -15,17 +17,13 @@ module ActiveRecord
15
17
  # association.
16
18
  attr_reader :base_klass, :children
17
19
 
18
- delegate :table_name, :column_names, :primary_key, :to => :base_klass
20
+ delegate :table_name, :column_names, :primary_key, to: :base_klass
19
21
 
20
22
  def initialize(base_klass, children)
21
23
  @base_klass = base_klass
22
24
  @children = children
23
25
  end
24
26
 
25
- def name
26
- reflection.name
27
- end
28
-
29
27
  def match?(other)
30
28
  self.class == other.class
31
29
  end
@@ -35,13 +33,15 @@ module ActiveRecord
35
33
  children.each { |child| child.each(&block) }
36
34
  end
37
35
 
38
- # An Arel::Table for the active_record
39
- def table
40
- raise NotImplementedError
36
+ def each_children(&block)
37
+ children.each do |child|
38
+ yield self, child
39
+ child.each_children(&block)
40
+ end
41
41
  end
42
42
 
43
- # The alias for the active_record's table
44
- def aliased_table_name
43
+ # An Arel::Table for the active_record
44
+ def table
45
45
  raise NotImplementedError
46
46
  end
47
47
 
@@ -54,16 +54,16 @@ module ActiveRecord
54
54
  length = column_names_with_alias.length
55
55
 
56
56
  while index < length
57
- column_name, alias_name = column_names_with_alias[index]
58
- hash[column_name] = row[alias_name]
57
+ column = column_names_with_alias[index]
58
+ hash[column.name] = row[column.alias]
59
59
  index += 1
60
60
  end
61
61
 
62
62
  hash
63
63
  end
64
64
 
65
- def instantiate(row, aliases)
66
- base_klass.instantiate(extract_record(row, aliases))
65
+ def instantiate(row, aliases, &block)
66
+ base_klass.instantiate(extract_record(row, aliases), &block)
67
67
  end
68
68
  end
69
69
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  # Implements the details of eager loading of Active Record associations.
@@ -42,16 +44,8 @@ module ActiveRecord
42
44
  extend ActiveSupport::Autoload
43
45
 
44
46
  eager_autoload do
45
- autoload :Association, 'active_record/associations/preloader/association'
46
- autoload :SingularAssociation, 'active_record/associations/preloader/singular_association'
47
- autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association'
48
- autoload :ThroughAssociation, 'active_record/associations/preloader/through_association'
49
-
50
- autoload :HasMany, 'active_record/associations/preloader/has_many'
51
- autoload :HasManyThrough, 'active_record/associations/preloader/has_many_through'
52
- autoload :HasOne, 'active_record/associations/preloader/has_one'
53
- autoload :HasOneThrough, 'active_record/associations/preloader/has_one_through'
54
- autoload :BelongsTo, 'active_record/associations/preloader/belongs_to'
47
+ autoload :Association, "active_record/associations/preloader/association"
48
+ autoload :ThroughAssociation, "active_record/associations/preloader/through_association"
55
49
  end
56
50
 
57
51
  # Eager loads the named associations for the given Active Record record(s).
@@ -88,18 +82,13 @@ module ActiveRecord
88
82
  # [ :books, :author ]
89
83
  # { author: :avatar }
90
84
  # [ :books, { author: :avatar } ]
91
-
92
- NULL_RELATION = Struct.new(:values, :bind_values).new({}, [])
93
-
94
85
  def preload(records, associations, preload_scope = nil)
95
- records = Array.wrap(records).compact.uniq
96
- associations = Array.wrap(associations)
97
- preload_scope = preload_scope || NULL_RELATION
86
+ records = Array.wrap(records).compact
98
87
 
99
88
  if records.empty?
100
89
  []
101
90
  else
102
- associations.flat_map { |association|
91
+ Array.wrap(associations).flat_map { |association|
103
92
  preloaders_on association, records, preload_scope
104
93
  }
105
94
  end
@@ -107,97 +96,106 @@ module ActiveRecord
107
96
 
108
97
  private
109
98
 
110
- def preloaders_on(association, records, scope)
111
- case association
112
- when Hash
113
- preloaders_for_hash(association, records, scope)
114
- when Symbol
115
- preloaders_for_one(association, records, scope)
116
- when String
117
- preloaders_for_one(association.to_sym, records, scope)
118
- else
119
- raise ArgumentError, "#{association.inspect} was not recognised for preload"
99
+ # Loads all the given data into +records+ for the +association+.
100
+ def preloaders_on(association, records, scope, polymorphic_parent = false)
101
+ case association
102
+ when Hash
103
+ preloaders_for_hash(association, records, scope, polymorphic_parent)
104
+ when Symbol, String
105
+ preloaders_for_one(association, records, scope, polymorphic_parent)
106
+ else
107
+ raise ArgumentError, "#{association.inspect} was not recognized for preload"
108
+ end
120
109
  end
121
- end
122
-
123
- def preloaders_for_hash(association, records, scope)
124
- association.flat_map { |parent, child|
125
- loaders = preloaders_for_one parent, records, scope
126
110
 
127
- recs = loaders.flat_map(&:preloaded_records).uniq
128
- loaders.concat Array.wrap(child).flat_map { |assoc|
129
- preloaders_on assoc, recs, scope
111
+ def preloaders_for_hash(association, records, scope, polymorphic_parent)
112
+ association.flat_map { |parent, child|
113
+ grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records|
114
+ loaders = preloaders_for_reflection(reflection, reflection_records, scope)
115
+ recs = loaders.flat_map(&:preloaded_records)
116
+ child_polymorphic_parent = reflection && reflection.options[:polymorphic]
117
+ loaders.concat Array.wrap(child).flat_map { |assoc|
118
+ preloaders_on assoc, recs, scope, child_polymorphic_parent
119
+ }
120
+ loaders
121
+ end
130
122
  }
131
- loaders
132
- }
133
- end
134
-
135
- # Not all records have the same class, so group then preload group on the reflection
136
- # itself so that if various subclass share the same association then we do not split
137
- # them unnecessarily
138
- #
139
- # Additionally, polymorphic belongs_to associations can have multiple associated
140
- # classes, depending on the polymorphic_type field. So we group by the classes as
141
- # well.
142
- def preloaders_for_one(association, records, scope)
143
- grouped_records(association, records).flat_map do |reflection, klasses|
144
- klasses.map do |rhs_klass, rs|
145
- loader = preloader_for(reflection, rs, rhs_klass).new(rhs_klass, rs, reflection, scope)
146
- loader.run self
147
- loader
148
- end
149
123
  end
150
- end
151
124
 
152
- def grouped_records(association, records)
153
- h = {}
154
- records.each do |record|
155
- next unless record
156
- assoc = record.association(association)
157
- klasses = h[assoc.reflection] ||= {}
158
- (klasses[assoc.klass] ||= []) << record
125
+ # Loads all the given data into +records+ for a singular +association+.
126
+ #
127
+ # Functions by instantiating a preloader class such as Preloader::Association and
128
+ # call the +run+ method for each passed in class in the +records+ argument.
129
+ #
130
+ # Not all records have the same class, so group then preload group on the reflection
131
+ # itself so that if various subclass share the same association then we do not split
132
+ # them unnecessarily
133
+ #
134
+ # Additionally, polymorphic belongs_to associations can have multiple associated
135
+ # classes, depending on the polymorphic_type field. So we group by the classes as
136
+ # well.
137
+ def preloaders_for_one(association, records, scope, polymorphic_parent)
138
+ grouped_records(association, records, polymorphic_parent)
139
+ .flat_map do |reflection, reflection_records|
140
+ preloaders_for_reflection reflection, reflection_records, scope
141
+ end
159
142
  end
160
- h
161
- end
162
143
 
163
- class AlreadyLoaded # :nodoc:
164
- attr_reader :owners, :reflection
144
+ def preloaders_for_reflection(reflection, records, scope)
145
+ records.group_by { |record| record.association(reflection.name).klass }.map do |rhs_klass, rs|
146
+ preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope).run
147
+ end
148
+ end
165
149
 
166
- def initialize(klass, owners, reflection, preload_scope)
167
- @owners = owners
168
- @reflection = reflection
150
+ def grouped_records(association, records, polymorphic_parent)
151
+ h = {}
152
+ records.each do |record|
153
+ reflection = record.class._reflect_on_association(association)
154
+ next if polymorphic_parent && !reflection || !record.association(association).klass
155
+ (h[reflection] ||= []) << record
156
+ end
157
+ h
169
158
  end
170
159
 
171
- def run(preloader); end
160
+ class AlreadyLoaded # :nodoc:
161
+ def initialize(klass, owners, reflection, preload_scope)
162
+ @owners = owners
163
+ @reflection = reflection
164
+ end
172
165
 
173
- def preloaded_records
174
- owners.flat_map { |owner| owner.association(reflection.name).target }
175
- end
176
- end
166
+ def run
167
+ self
168
+ end
177
169
 
178
- class NullPreloader # :nodoc:
179
- def self.new(klass, owners, reflection, preload_scope); self; end
180
- def self.run(preloader); end
181
- def self.preloaded_records; []; end
182
- end
170
+ def preloaded_records
171
+ @preloaded_records ||= records_by_owner.flat_map(&:last)
172
+ end
183
173
 
184
- def preloader_for(reflection, owners, rhs_klass)
185
- return NullPreloader unless rhs_klass
174
+ def records_by_owner
175
+ @records_by_owner ||= owners.each_with_object({}) do |owner, result|
176
+ result[owner] = Array(owner.association(reflection.name).target)
177
+ end
178
+ end
186
179
 
187
- if owners.first.association(reflection.name).loaded?
188
- return AlreadyLoaded
180
+ private
181
+ attr_reader :owners, :reflection
189
182
  end
190
- reflection.check_preloadable!
191
-
192
- case reflection.macro
193
- when :has_many
194
- reflection.options[:through] ? HasManyThrough : HasMany
195
- when :has_one
196
- reflection.options[:through] ? HasOneThrough : HasOne
197
- when :belongs_to
198
- BelongsTo
183
+
184
+ # Returns a class containing the logic needed to load preload the data
185
+ # and attach it to a relation. The class returned implements a `run` method
186
+ # that accepts a preloader.
187
+ def preloader_for(reflection, owners)
188
+ if owners.first.association(reflection.name).loaded?
189
+ return AlreadyLoaded
190
+ end
191
+ reflection.check_preloadable!
192
+
193
+ if reflection.options[:through]
194
+ ThroughAssociation
195
+ else
196
+ Association
197
+ end
199
198
  end
200
- end
201
199
  end
202
200
  end
203
201
  end