activerecord 4.2.11.1 → 6.0.3.5

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 +721 -1522
  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,52 +1,45 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  class JoinDependency # :nodoc:
4
- autoload :JoinBase, 'active_record/associations/join_dependency/join_base'
5
- autoload :JoinAssociation, 'active_record/associations/join_dependency/join_association'
6
+ autoload :JoinBase, "active_record/associations/join_dependency/join_base"
7
+ autoload :JoinAssociation, "active_record/associations/join_dependency/join_association"
6
8
 
7
9
  class Aliases # :nodoc:
8
10
  def initialize(tables)
9
11
  @tables = tables
10
- @alias_cache = tables.each_with_object({}) { |table,h|
11
- h[table.node] = table.columns.each_with_object({}) { |column,i|
12
+ @alias_cache = tables.each_with_object({}) { |table, h|
13
+ h[table.node] = table.columns.each_with_object({}) { |column, i|
12
14
  i[column.name] = column.alias
13
15
  }
14
16
  }
15
- @name_and_alias_cache = tables.each_with_object({}) { |table,h|
16
- h[table.node] = table.columns.map { |column|
17
- [column.name, column.alias]
18
- }
17
+ @columns_cache = tables.each_with_object({}) { |table, h|
18
+ h[table.node] = table.columns
19
19
  }
20
20
  end
21
21
 
22
22
  def columns
23
- @tables.flat_map { |t| t.column_aliases }
23
+ @tables.flat_map(&:column_aliases)
24
24
  end
25
25
 
26
- # An array of [column_name, alias] pairs for the table
27
26
  def column_aliases(node)
28
- @name_and_alias_cache[node]
27
+ @columns_cache[node]
29
28
  end
30
29
 
31
30
  def column_alias(node, column)
32
31
  @alias_cache[node][column]
33
32
  end
34
33
 
35
- class Table < Struct.new(:node, :columns)
36
- def table
37
- Arel::Nodes::TableAlias.new node.table, node.aliased_table_name
38
- end
39
-
34
+ Table = Struct.new(:node, :columns) do # :nodoc:
40
35
  def column_aliases
41
- t = table
36
+ t = node.table
42
37
  columns.map { |column| t[column.name].as Arel.sql column.alias }
43
38
  end
44
39
  end
45
40
  Column = Struct.new(:name, :alias)
46
41
  end
47
42
 
48
- attr_reader :alias_tracker, :base_klass, :join_root
49
-
50
43
  def self.make_tree(associations)
51
44
  hash = {}
52
45
  walk_tree associations, hash
@@ -62,7 +55,7 @@ module ActiveRecord
62
55
  walk_tree assoc, hash
63
56
  end
64
57
  when Hash
65
- associations.each do |k,v|
58
+ associations.each do |k, v|
66
59
  cache = hash[k] ||= {}
67
60
  walk_tree v, cache
68
61
  end
@@ -71,76 +64,50 @@ module ActiveRecord
71
64
  end
72
65
  end
73
66
 
74
- # base is the base class on which operation is taking place.
75
- # associations is the list of associations which are joined using hash, symbol or array.
76
- # joins is the list of all string join commands and arel nodes.
77
- #
78
- # Example :
79
- #
80
- # class Physician < ActiveRecord::Base
81
- # has_many :appointments
82
- # has_many :patients, through: :appointments
83
- # end
84
- #
85
- # If I execute `@physician.patients.to_a` then
86
- # base # => Physician
87
- # associations # => []
88
- # joins # => [#<Arel::Nodes::InnerJoin: ...]
89
- #
90
- # However if I execute `Physician.joins(:appointments).to_a` then
91
- # base # => Physician
92
- # associations # => [:appointments]
93
- # joins # => []
94
- #
95
- def initialize(base, associations, joins)
96
- @alias_tracker = AliasTracker.create(base.connection, joins)
97
- @alias_tracker.aliased_table_for(base.table_name, base.table_name) # Updates the count for base.table_name to 1
67
+ def initialize(base, table, associations, join_type)
98
68
  tree = self.class.make_tree associations
99
- @join_root = JoinBase.new base, build(tree, base)
100
- @join_root.children.each { |child| construct_tables! @join_root, child }
69
+ @join_root = JoinBase.new(base, table, build(tree, base))
70
+ @join_type = join_type
71
+ end
72
+
73
+ def base_klass
74
+ join_root.base_klass
101
75
  end
102
76
 
103
77
  def reflections
104
78
  join_root.drop(1).map!(&:reflection)
105
79
  end
106
80
 
107
- def join_constraints(outer_joins)
108
- joins = join_root.children.flat_map { |child|
109
- make_inner_joins join_root, child
110
- }
81
+ def join_constraints(joins_to_add, alias_tracker)
82
+ @alias_tracker = alias_tracker
111
83
 
112
- joins.concat outer_joins.flat_map { |oj|
84
+ construct_tables!(join_root)
85
+ joins = make_join_constraints(join_root, join_type)
86
+
87
+ joins.concat joins_to_add.flat_map { |oj|
88
+ construct_tables!(oj.join_root)
113
89
  if join_root.match? oj.join_root
114
- walk join_root, oj.join_root
90
+ walk(join_root, oj.join_root, oj.join_type)
115
91
  else
116
- oj.join_root.children.flat_map { |child|
117
- make_outer_joins oj.join_root, child
118
- }
92
+ make_join_constraints(oj.join_root, oj.join_type)
119
93
  end
120
94
  }
121
95
  end
122
96
 
123
- def aliases
124
- Aliases.new join_root.each_with_index.map { |join_part,i|
125
- columns = join_part.column_names.each_with_index.map { |column_name,j|
126
- Aliases::Column.new column_name, "t#{i}_r#{j}"
127
- }
128
- Aliases::Table.new(join_part, columns)
129
- }
130
- end
131
-
132
- def instantiate(result_set, aliases)
97
+ def instantiate(result_set, &block)
133
98
  primary_key = aliases.column_alias(join_root, join_root.primary_key)
134
99
 
135
- seen = Hash.new { |h,parent_klass|
136
- h[parent_klass] = Hash.new { |i,parent_id|
137
- i[parent_id] = Hash.new { |j,child_klass| j[child_klass] = {} }
100
+ seen = Hash.new { |i, object_id|
101
+ i[object_id] = Hash.new { |j, child_class|
102
+ j[child_class] = {}
138
103
  }
139
104
  }
140
105
 
141
- model_cache = Hash.new { |h,klass| h[klass] = {} }
106
+ model_cache = Hash.new { |h, klass| h[klass] = {} }
142
107
  parents = model_cache[join_root]
108
+
143
109
  column_aliases = aliases.column_aliases join_root
110
+ column_aliases += explicit_selections(column_aliases, result_set)
144
111
 
145
112
  message_bus = ActiveSupport::Notifications.instrumenter
146
113
 
@@ -149,140 +116,156 @@ module ActiveRecord
149
116
  class_name: join_root.base_klass.name
150
117
  }
151
118
 
152
- message_bus.instrument('instantiation.active_record', payload) do
119
+ message_bus.instrument("instantiation.active_record", payload) do
153
120
  result_set.each { |row_hash|
154
121
  parent_key = primary_key ? row_hash[primary_key] : row_hash
155
- parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases)
156
- construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
122
+ parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, &block)
123
+ construct(parent, join_root, row_hash, seen, model_cache)
157
124
  }
158
125
  end
159
126
 
160
127
  parents.values
161
128
  end
162
129
 
130
+ def apply_column_aliases(relation)
131
+ relation._select!(-> { aliases.columns })
132
+ end
133
+
134
+ protected
135
+ attr_reader :join_root, :join_type
136
+
163
137
  private
138
+ attr_reader :alias_tracker
164
139
 
165
- def make_constraints(parent, child, tables, join_type)
166
- chain = child.reflection.chain
167
- foreign_table = parent.table
168
- foreign_klass = parent.base_klass
169
- child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain)
170
- end
140
+ def explicit_selections(root_column_aliases, result_set)
141
+ root_names = root_column_aliases.map(&:name).to_set
142
+ result_set.columns
143
+ .reject { |n| root_names.include?(n) || n =~ /\At\d+_r\d+\z/ }
144
+ .map { |n| Aliases::Column.new(n, n) }
145
+ end
171
146
 
172
- def make_outer_joins(parent, child)
173
- tables = table_aliases_for(parent, child)
174
- join_type = Arel::Nodes::OuterJoin
175
- info = make_constraints parent, child, tables, join_type
147
+ def aliases
148
+ @aliases ||= Aliases.new join_root.each_with_index.map { |join_part, i|
149
+ columns = join_part.column_names.each_with_index.map { |column_name, j|
150
+ Aliases::Column.new column_name, "t#{i}_r#{j}"
151
+ }
152
+ Aliases::Table.new(join_part, columns)
153
+ }
154
+ end
176
155
 
177
- [info] + child.children.flat_map { |c| make_outer_joins(child, c) }
178
- end
156
+ def construct_tables!(join_root)
157
+ join_root.each_children do |parent, child|
158
+ child.tables = table_aliases_for(parent, child)
159
+ end
160
+ end
179
161
 
180
- def make_inner_joins(parent, child)
181
- tables = child.tables
182
- join_type = Arel::Nodes::InnerJoin
183
- info = make_constraints parent, child, tables, join_type
162
+ def make_join_constraints(join_root, join_type)
163
+ join_root.children.flat_map do |child|
164
+ make_constraints(join_root, child, join_type)
165
+ end
166
+ end
184
167
 
185
- [info] + child.children.flat_map { |c| make_inner_joins(child, c) }
186
- end
168
+ def make_constraints(parent, child, join_type)
169
+ foreign_table = parent.table
170
+ foreign_klass = parent.base_klass
171
+ joins = child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
172
+ joins.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
173
+ end
187
174
 
188
- def table_aliases_for(parent, node)
189
- node.reflection.chain.map { |reflection|
190
- alias_tracker.aliased_table_for(
191
- reflection.table_name,
192
- table_alias_for(reflection, parent, reflection != node.reflection)
193
- )
194
- }
195
- end
175
+ def table_aliases_for(parent, node)
176
+ node.reflection.chain.map { |reflection|
177
+ alias_tracker.aliased_table_for(
178
+ reflection.table_name,
179
+ table_alias_for(reflection, parent, reflection != node.reflection),
180
+ reflection.klass.type_caster
181
+ )
182
+ }
183
+ end
196
184
 
197
- def construct_tables!(parent, node)
198
- node.tables = table_aliases_for(parent, node)
199
- node.children.each { |child| construct_tables! node, child }
200
- end
185
+ def table_alias_for(reflection, parent, join)
186
+ name = reflection.alias_candidate(parent.table_name)
187
+ join ? "#{name}_join" : name
188
+ end
201
189
 
202
- def table_alias_for(reflection, parent, join)
203
- name = "#{reflection.plural_name}_#{parent.table_name}"
204
- name << "_join" if join
205
- name
206
- end
190
+ def walk(left, right, join_type)
191
+ intersection, missing = right.children.map { |node1|
192
+ [left.children.find { |node2| node1.match? node2 }, node1]
193
+ }.partition(&:first)
207
194
 
208
- def walk(left, right)
209
- intersection, missing = right.children.map { |node1|
210
- [left.children.find { |node2| node1.match? node2 }, node1]
211
- }.partition(&:first)
195
+ joins = intersection.flat_map { |l, r| r.table = l.table; walk(l, r, join_type) }
196
+ joins.concat missing.flat_map { |_, n| make_constraints(left, n, join_type) }
197
+ end
212
198
 
213
- ojs = missing.flat_map { |_,n| make_outer_joins left, n }
214
- intersection.flat_map { |l,r| walk l, r }.concat ojs
215
- end
199
+ def find_reflection(klass, name)
200
+ klass._reflect_on_association(name) ||
201
+ raise(ConfigurationError, "Can't join '#{klass.name}' to association named '#{name}'; perhaps you misspelled it?")
202
+ end
216
203
 
217
- def find_reflection(klass, name)
218
- klass._reflect_on_association(name) or
219
- raise ConfigurationError, "Association named '#{ name }' was not found on #{ klass.name }; perhaps you misspelled it?"
220
- end
204
+ def build(associations, base_klass)
205
+ associations.map do |name, right|
206
+ reflection = find_reflection base_klass, name
207
+ reflection.check_validity!
208
+ reflection.check_eager_loadable!
221
209
 
222
- def build(associations, base_klass)
223
- associations.map do |name, right|
224
- reflection = find_reflection base_klass, name
225
- reflection.check_validity!
226
- reflection.check_eager_loadable!
210
+ if reflection.polymorphic?
211
+ raise EagerLoadPolymorphicError.new(reflection)
212
+ end
227
213
 
228
- if reflection.polymorphic?
229
- raise EagerLoadPolymorphicError.new(reflection)
214
+ JoinAssociation.new(reflection, build(right, reflection.klass))
230
215
  end
231
-
232
- JoinAssociation.new reflection, build(right, reflection.klass)
233
216
  end
234
- end
235
217
 
236
- def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
237
- return if ar_parent.nil?
238
- primary_id = ar_parent.id
218
+ def construct(ar_parent, parent, row, seen, model_cache)
219
+ return if ar_parent.nil?
239
220
 
240
- parent.children.each do |node|
241
- if node.reflection.collection?
242
- other = ar_parent.association(node.reflection.name)
243
- other.loaded!
244
- else
245
- if ar_parent.association_cache.key?(node.reflection.name)
221
+ parent.children.each do |node|
222
+ if node.reflection.collection?
223
+ other = ar_parent.association(node.reflection.name)
224
+ other.loaded!
225
+ elsif ar_parent.association_cached?(node.reflection.name)
246
226
  model = ar_parent.association(node.reflection.name).target
247
- construct(model, node, row, rs, seen, model_cache, aliases)
227
+ construct(model, node, row, seen, model_cache)
248
228
  next
249
229
  end
250
- end
251
230
 
252
- key = aliases.column_alias(node, node.primary_key)
253
- id = row[key]
254
- if id.nil?
255
- nil_association = ar_parent.association(node.reflection.name)
256
- nil_association.loaded!
257
- next
258
- end
231
+ key = aliases.column_alias(node, node.primary_key)
232
+ id = row[key]
233
+ if id.nil?
234
+ nil_association = ar_parent.association(node.reflection.name)
235
+ nil_association.loaded!
236
+ next
237
+ end
259
238
 
260
- model = seen[parent.base_klass][primary_id][node.base_klass][id]
239
+ model = seen[ar_parent.object_id][node][id]
261
240
 
262
- if model
263
- construct(model, node, row, rs, seen, model_cache, aliases)
264
- else
265
- model = construct_model(ar_parent, node, row, model_cache, id, aliases)
266
- seen[parent.base_klass][primary_id][node.base_klass][id] = model
267
- construct(model, node, row, rs, seen, model_cache, aliases)
241
+ if model
242
+ construct(model, node, row, seen, model_cache)
243
+ else
244
+ model = construct_model(ar_parent, node, row, model_cache, id)
245
+
246
+ seen[ar_parent.object_id][node][id] = model
247
+ construct(model, node, row, seen, model_cache)
248
+ end
268
249
  end
269
250
  end
270
- end
271
251
 
272
- def construct_model(record, node, row, model_cache, id, aliases)
273
- model = model_cache[node][id] ||= node.instantiate(row,
274
- aliases.column_aliases(node))
275
- other = record.association(node.reflection.name)
252
+ def construct_model(record, node, row, model_cache, id)
253
+ other = record.association(node.reflection.name)
276
254
 
277
- if node.reflection.collection?
278
- other.target.push(model)
279
- else
280
- other.target = model
281
- end
255
+ model = model_cache[node][id] ||=
256
+ node.instantiate(row, aliases.column_aliases(node)) do |m|
257
+ other.set_inverse_instance(m)
258
+ end
282
259
 
283
- other.set_inverse_instance(model)
284
- model
285
- end
260
+ if node.reflection.collection?
261
+ other.target.push(model)
262
+ else
263
+ other.target = model
264
+ end
265
+
266
+ model.readonly! if node.readonly?
267
+ model
268
+ end
286
269
  end
287
270
  end
288
271
  end