activerecord 5.0.7.2 → 6.0.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +844 -1944
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +18 -14
  10. data/lib/active_record/associations/alias_tracker.rb +24 -34
  11. data/lib/active_record/associations/association.rb +113 -55
  12. data/lib/active_record/associations/association_scope.rb +102 -96
  13. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +18 -25
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  19. data/lib/active_record/associations/builder/has_many.rb +4 -0
  20. data/lib/active_record/associations/builder/has_one.rb +37 -1
  21. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  22. data/lib/active_record/associations/collection_association.rb +93 -254
  23. data/lib/active_record/associations/collection_proxy.rb +159 -122
  24. data/lib/active_record/associations/foreign_association.rb +9 -0
  25. data/lib/active_record/associations/has_many_association.rb +23 -30
  26. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  27. data/lib/active_record/associations/has_one_association.rb +59 -54
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +152 -177
  33. data/lib/active_record/associations/preloader/association.rb +101 -97
  34. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  35. data/lib/active_record/associations/preloader.rb +94 -103
  36. data/lib/active_record/associations/singular_association.rb +12 -45
  37. data/lib/active_record/associations/through_association.rb +27 -15
  38. data/lib/active_record/associations.rb +1603 -1592
  39. data/lib/active_record/attribute_assignment.rb +54 -61
  40. data/lib/active_record/attribute_decorators.rb +38 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  43. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  44. data/lib/active_record/attribute_methods/query.rb +4 -3
  45. data/lib/active_record/attribute_methods/read.rb +20 -49
  46. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  48. data/lib/active_record/attribute_methods/write.rb +34 -33
  49. data/lib/active_record/attribute_methods.rb +66 -106
  50. data/lib/active_record/attributes.rb +38 -25
  51. data/lib/active_record/autosave_association.rb +58 -39
  52. data/lib/active_record/base.rb +27 -24
  53. data/lib/active_record/callbacks.rb +64 -35
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +34 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
  69. data/lib/active_record/connection_adapters/column.rb +41 -13
  70. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  99. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  117. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +261 -267
  127. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  128. data/lib/active_record/connection_handling.rb +143 -40
  129. data/lib/active_record/core.rb +207 -160
  130. data/lib/active_record/counter_cache.rb +60 -28
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -87
  137. data/lib/active_record/enum.rb +67 -23
  138. data/lib/active_record/errors.rb +114 -18
  139. data/lib/active_record/explain.rb +4 -4
  140. data/lib/active_record/explain_registry.rb +3 -1
  141. data/lib/active_record/explain_subscriber.rb +9 -4
  142. data/lib/active_record/fixture_set/file.rb +13 -8
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +194 -504
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +150 -99
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +116 -25
  152. data/lib/active_record/internal_metadata.rb +16 -19
  153. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  154. data/lib/active_record/locking/optimistic.rb +85 -86
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +48 -29
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  159. data/lib/active_record/middleware/database_selector.rb +74 -0
  160. data/lib/active_record/migration/command_recorder.rb +134 -100
  161. data/lib/active_record/migration/compatibility.rb +174 -56
  162. data/lib/active_record/migration/join_table.rb +8 -7
  163. data/lib/active_record/migration.rb +369 -302
  164. data/lib/active_record/model_schema.rb +160 -127
  165. data/lib/active_record/nested_attributes.rb +213 -202
  166. data/lib/active_record/no_touching.rb +12 -3
  167. data/lib/active_record/null_relation.rb +12 -34
  168. data/lib/active_record/persistence.rb +446 -77
  169. data/lib/active_record/query_cache.rb +13 -12
  170. data/lib/active_record/querying.rb +37 -24
  171. data/lib/active_record/railtie.rb +128 -36
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +312 -177
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +214 -254
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  179. data/lib/active_record/relation/batches.rb +98 -52
  180. data/lib/active_record/relation/calculations.rb +212 -173
  181. data/lib/active_record/relation/delegation.rb +73 -69
  182. data/lib/active_record/relation/finder_methods.rb +207 -247
  183. data/lib/active_record/relation/from_clause.rb +6 -8
  184. data/lib/active_record/relation/merger.rb +82 -61
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  192. data/lib/active_record/relation/predicate_builder.rb +83 -105
  193. data/lib/active_record/relation/query_attribute.rb +33 -2
  194. data/lib/active_record/relation/query_methods.rb +488 -332
  195. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  196. data/lib/active_record/relation/spawn_methods.rb +8 -8
  197. data/lib/active_record/relation/where_clause.rb +111 -96
  198. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  199. data/lib/active_record/relation.rb +443 -318
  200. data/lib/active_record/result.rb +69 -40
  201. data/lib/active_record/runtime_registry.rb +5 -3
  202. data/lib/active_record/sanitization.rb +83 -99
  203. data/lib/active_record/schema.rb +7 -14
  204. data/lib/active_record/schema_dumper.rb +71 -69
  205. data/lib/active_record/schema_migration.rb +16 -6
  206. data/lib/active_record/scoping/default.rb +92 -95
  207. data/lib/active_record/scoping/named.rb +51 -26
  208. data/lib/active_record/scoping.rb +20 -20
  209. data/lib/active_record/secure_token.rb +4 -2
  210. data/lib/active_record/serialization.rb +2 -0
  211. data/lib/active_record/statement_cache.rb +63 -28
  212. data/lib/active_record/store.rb +121 -41
  213. data/lib/active_record/suppressor.rb +6 -3
  214. data/lib/active_record/table_metadata.rb +39 -18
  215. data/lib/active_record/tasks/database_tasks.rb +271 -81
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +243 -0
  221. data/lib/active_record/timestamp.rb +70 -36
  222. data/lib/active_record/touch_later.rb +8 -6
  223. data/lib/active_record/transactions.rb +141 -157
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  226. data/lib/active_record/type/date.rb +2 -0
  227. data/lib/active_record/type/date_time.rb +2 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  230. data/lib/active_record/type/internal/timezone.rb +2 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +16 -9
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +12 -1
  235. data/lib/active_record/type/type_map.rb +14 -17
  236. data/lib/active_record/type/unsigned_integer.rb +16 -0
  237. data/lib/active_record/type.rb +23 -18
  238. data/lib/active_record/type_caster/connection.rb +17 -12
  239. data/lib/active_record/type_caster/map.rb +5 -4
  240. data/lib/active_record/type_caster.rb +4 -2
  241. data/lib/active_record/validations/absence.rb +2 -0
  242. data/lib/active_record/validations/associated.rb +3 -2
  243. data/lib/active_record/validations/length.rb +2 -0
  244. data/lib/active_record/validations/presence.rb +4 -2
  245. data/lib/active_record/validations/uniqueness.rb +29 -42
  246. data/lib/active_record/validations.rb +7 -5
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +37 -22
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +256 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +203 -0
  315. data/lib/arel/visitors/dot.rb +296 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +156 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +158 -0
  321. data/lib/arel/visitors/oracle12.rb +65 -0
  322. data/lib/arel/visitors/postgresql.rb +109 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +888 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors/where_sql.rb +22 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +62 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -3
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record.rb +7 -5
  338. metadata +138 -52
  339. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  340. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  341. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  343. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  344. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  345. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  346. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  349. data/lib/active_record/attribute_set/builder.rb +0 -132
  350. data/lib/active_record/attribute_set.rb +0 -110
  351. data/lib/active_record/collection_cache_key.rb +0 -50
  352. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  353. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  354. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  355. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  356. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  357. data/lib/active_record/type/internal/abstract_json.rb +0 -33
  358. /data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  359. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,5 +1,6 @@
1
- require 'thread'
2
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/filters"
3
4
 
4
5
  module ActiveRecord
5
6
  # = Active Record Reflection
@@ -7,37 +8,41 @@ module ActiveRecord
7
8
  extend ActiveSupport::Concern
8
9
 
9
10
  included do
10
- class_attribute :_reflections, instance_writer: false
11
- class_attribute :aggregate_reflections, instance_writer: false
12
- self._reflections = {}
13
- self.aggregate_reflections = {}
11
+ class_attribute :_reflections, instance_writer: false, default: {}
12
+ class_attribute :aggregate_reflections, instance_writer: false, default: {}
14
13
  end
15
14
 
16
- def self.create(macro, name, scope, options, ar)
17
- klass = case macro
18
- when :composed_of
19
- AggregateReflection
20
- when :has_many
21
- HasManyReflection
22
- when :has_one
23
- HasOneReflection
24
- when :belongs_to
25
- BelongsToReflection
26
- else
27
- raise "Unsupported Macro: #{macro}"
28
- end
29
-
30
- reflection = klass.new(name, scope, options, ar)
31
- options[:through] ? ThroughReflection.new(reflection) : reflection
32
- end
15
+ class << self
16
+ def create(macro, name, scope, options, ar)
17
+ reflection = reflection_class_for(macro).new(name, scope, options, ar)
18
+ options[:through] ? ThroughReflection.new(reflection) : reflection
19
+ end
33
20
 
34
- def self.add_reflection(ar, name, reflection)
35
- ar.clear_reflections_cache
36
- ar._reflections = ar._reflections.merge(name.to_s => reflection)
37
- end
21
+ def add_reflection(ar, name, reflection)
22
+ ar.clear_reflections_cache
23
+ name = -name.to_s
24
+ ar._reflections = ar._reflections.except(name).merge!(name => reflection)
25
+ end
38
26
 
39
- def self.add_aggregate_reflection(ar, name, reflection)
40
- ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection)
27
+ def add_aggregate_reflection(ar, name, reflection)
28
+ ar.aggregate_reflections = ar.aggregate_reflections.merge(-name.to_s => reflection)
29
+ end
30
+
31
+ private
32
+ def reflection_class_for(macro)
33
+ case macro
34
+ when :composed_of
35
+ AggregateReflection
36
+ when :has_many
37
+ HasManyReflection
38
+ when :has_one
39
+ HasOneReflection
40
+ when :belongs_to
41
+ BelongsToReflection
42
+ else
43
+ raise "Unsupported Macro: #{macro}"
44
+ end
45
+ end
41
46
  end
42
47
 
43
48
  # \Reflection enables the ability to examine the associations and aggregations of
@@ -135,8 +140,8 @@ module ActiveRecord
135
140
  # BelongsToReflection
136
141
  # HasAndBelongsToManyReflection
137
142
  # ThroughReflection
138
- # PolymorphicReflection
139
- # RuntimeReflection
143
+ # PolymorphicReflection
144
+ # RuntimeReflection
140
145
  class AbstractReflection # :nodoc:
141
146
  def through_reflection?
142
147
  false
@@ -152,14 +157,6 @@ module ActiveRecord
152
157
  klass.new(attributes, &block)
153
158
  end
154
159
 
155
- def quoted_table_name
156
- klass.quoted_table_name
157
- end
158
-
159
- def primary_key_type
160
- klass.type_for_attribute(klass.primary_key)
161
- end
162
-
163
160
  # Returns the class name for the macro.
164
161
  #
165
162
  # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
@@ -170,12 +167,54 @@ module ActiveRecord
170
167
 
171
168
  JoinKeys = Struct.new(:key, :foreign_key) # :nodoc:
172
169
 
173
- def join_keys(association_klass)
174
- JoinKeys.new(foreign_key, active_record_primary_key)
170
+ def join_keys
171
+ @join_keys ||= get_join_keys(klass)
172
+ end
173
+
174
+ # Returns a list of scopes that should be applied for this Reflection
175
+ # object when querying the database.
176
+ def scopes
177
+ scope ? [scope] : []
178
+ end
179
+
180
+ def join_scope(table, foreign_table, foreign_klass)
181
+ predicate_builder = predicate_builder(table)
182
+ scope_chain_items = join_scopes(table, predicate_builder)
183
+ klass_scope = klass_join_scope(table, predicate_builder)
184
+
185
+ if type
186
+ klass_scope.where!(type => foreign_klass.polymorphic_name)
187
+ end
188
+
189
+ scope_chain_items.inject(klass_scope, &:merge!)
190
+
191
+ key = join_keys.key
192
+ foreign_key = join_keys.foreign_key
193
+
194
+ klass_scope.where!(table[key].eq(foreign_table[foreign_key]))
195
+
196
+ if klass.finder_needs_type_condition?
197
+ klass_scope.where!(klass.send(:type_condition, table))
198
+ end
199
+
200
+ klass_scope
201
+ end
202
+
203
+ def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
204
+ if scope
205
+ [scope_for(build_scope(table, predicate_builder, klass))]
206
+ else
207
+ []
208
+ end
209
+ end
210
+
211
+ def klass_join_scope(table, predicate_builder) # :nodoc:
212
+ relation = build_scope(table, predicate_builder)
213
+ klass.scope_for_association(relation)
175
214
  end
176
215
 
177
216
  def constraints
178
- scope_chain.flatten
217
+ chain.flat_map(&:scopes)
179
218
  end
180
219
 
181
220
  def counter_cache_column
@@ -247,6 +286,40 @@ module ActiveRecord
247
286
  def chain
248
287
  collect_join_chain
249
288
  end
289
+
290
+ def get_join_keys(association_klass)
291
+ JoinKeys.new(join_primary_key(association_klass), join_foreign_key)
292
+ end
293
+
294
+ def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass)
295
+ Relation.create(
296
+ klass,
297
+ table: table,
298
+ predicate_builder: predicate_builder
299
+ )
300
+ end
301
+
302
+ def join_primary_key(*)
303
+ foreign_key
304
+ end
305
+
306
+ def join_foreign_key
307
+ active_record_primary_key
308
+ end
309
+
310
+ protected
311
+ def actual_source_reflection # FIXME: this is a horrible name
312
+ self
313
+ end
314
+
315
+ private
316
+ def predicate_builder(table)
317
+ PredicateBuilder.new(TableMetadata.new(klass, table))
318
+ end
319
+
320
+ def primary_key(klass)
321
+ klass.primary_key || raise(UnknownPrimaryKey.new(klass))
322
+ end
250
323
  end
251
324
 
252
325
  # Base class for AggregateReflection and AssociationReflection. Objects of
@@ -281,7 +354,6 @@ module ActiveRecord
281
354
  end
282
355
 
283
356
  def autosave=(autosave)
284
- @automatic_inverse_of = false
285
357
  @options[:autosave] = autosave
286
358
  parent_reflection = self.parent_reflection
287
359
  if parent_reflection
@@ -293,6 +365,17 @@ module ActiveRecord
293
365
  #
294
366
  # <tt>composed_of :balance, class_name: 'Money'</tt> returns the Money class
295
367
  # <tt>has_many :clients</tt> returns the Client class
368
+ #
369
+ # class Company < ActiveRecord::Base
370
+ # has_many :clients
371
+ # end
372
+ #
373
+ # Company.reflect_on_association(:clients).klass
374
+ # # => Client
375
+ #
376
+ # <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
377
+ # a new association object. Use +build_association+ or +create_association+
378
+ # instead. This allows plugins to hook into association object creation.
296
379
  def klass
297
380
  @klass ||= compute_class(class_name)
298
381
  end
@@ -311,8 +394,8 @@ module ActiveRecord
311
394
  active_record == other_aggregation.active_record
312
395
  end
313
396
 
314
- def scope_for(klass)
315
- scope ? klass.unscoped.instance_exec(nil, &scope) : klass.unscoped
397
+ def scope_for(relation, owner = nil)
398
+ relation.instance_exec(owner, &scope) || relation
316
399
  end
317
400
 
318
401
  private
@@ -321,8 +404,7 @@ module ActiveRecord
321
404
  end
322
405
  end
323
406
 
324
-
325
- # Holds all the meta-data about an aggregation as it was specified in the
407
+ # Holds all the metadata about an aggregation as it was specified in the
326
408
  # Active Record class.
327
409
  class AggregateReflection < MacroReflection #:nodoc:
328
410
  def mapping
@@ -331,26 +413,13 @@ module ActiveRecord
331
413
  end
332
414
  end
333
415
 
334
- # Holds all the meta-data about an association as it was specified in the
416
+ # Holds all the metadata about an association as it was specified in the
335
417
  # Active Record class.
336
418
  class AssociationReflection < MacroReflection #:nodoc:
337
- # Returns the target association's class.
338
- #
339
- # class Author < ActiveRecord::Base
340
- # has_many :books
341
- # end
342
- #
343
- # Author.reflect_on_association(:books).klass
344
- # # => Book
345
- #
346
- # <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
347
- # a new association object. Use +build_association+ or +create_association+
348
- # instead. This allows plugins to hook into association object creation.
349
- def klass
350
- @klass ||= compute_class(class_name)
351
- end
352
-
353
419
  def compute_class(name)
420
+ if polymorphic?
421
+ raise ArgumentError, "Polymorphic associations do not support computing the class."
422
+ end
354
423
  active_record.send(:compute_type, name)
355
424
  end
356
425
 
@@ -359,22 +428,21 @@ module ActiveRecord
359
428
 
360
429
  def initialize(name, scope, options, active_record)
361
430
  super
362
- @automatic_inverse_of = nil
363
431
  @type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type")
364
- @foreign_type = options[:foreign_type] || "#{name}_type"
432
+ @foreign_type = options[:polymorphic] && (options[:foreign_type] || "#{name}_type")
365
433
  @constructable = calculate_constructable(macro, options)
366
- @association_scope_cache = {}
367
- @scope_lock = Mutex.new
434
+
435
+ if options[:class_name] && options[:class_name].class == Class
436
+ raise ArgumentError, "A class was passed to `:class_name` but we are expecting a string."
437
+ end
368
438
  end
369
439
 
370
- def association_scope_cache(conn, owner)
371
- key = conn.prepared_statements
440
+ def association_scope_cache(klass, owner, &block)
441
+ key = self
372
442
  if polymorphic?
373
443
  key = [key, owner._read_attribute(@foreign_type)]
374
444
  end
375
- @association_scope_cache[key] ||= @scope_lock.synchronize {
376
- @association_scope_cache[key] ||= yield
377
- }
445
+ klass.cached_find_by_statement(key, &block)
378
446
  end
379
447
 
380
448
  def constructable? # :nodoc:
@@ -398,10 +466,6 @@ module ActiveRecord
398
466
  options[:primary_key] || primary_key(klass || self.klass)
399
467
  end
400
468
 
401
- def association_primary_key_type
402
- klass.type_for_attribute(association_primary_key.to_s)
403
- end
404
-
405
469
  def active_record_primary_key
406
470
  @active_record_primary_key ||= options[:primary_key] || primary_key(active_record)
407
471
  end
@@ -413,7 +477,7 @@ module ActiveRecord
413
477
  def check_preloadable!
414
478
  return unless scope
415
479
 
416
- if scope.arity > 0
480
+ unless scope.arity == 0
417
481
  raise ArgumentError, <<-MSG.squish
418
482
  The association scope '#{name}' is instance dependent (the scope
419
483
  block takes an argument). Preloading instance dependent scopes is
@@ -424,7 +488,7 @@ module ActiveRecord
424
488
  alias :check_eager_loadable! :check_preloadable!
425
489
 
426
490
  def join_id_for(owner) # :nodoc:
427
- owner[active_record_primary_key]
491
+ owner[join_foreign_key]
428
492
  end
429
493
 
430
494
  def through_reflection
@@ -444,19 +508,13 @@ module ActiveRecord
444
508
  # This is for clearing cache on the reflection. Useful for tests that need to compare
445
509
  # SQL queries on associations.
446
510
  def clear_association_scope_cache # :nodoc:
447
- @association_scope_cache.clear
511
+ klass.initialize_find_by_cache
448
512
  end
449
513
 
450
514
  def nested?
451
515
  false
452
516
  end
453
517
 
454
- # An array of arrays of scopes. Each item in the outside array corresponds to a reflection
455
- # in the #chain.
456
- def scope_chain
457
- scope ? [[scope]] : [[]]
458
- end
459
-
460
518
  def has_scope?
461
519
  scope
462
520
  end
@@ -513,7 +571,7 @@ module ActiveRecord
513
571
  end
514
572
 
515
573
  VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to]
516
- INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :polymorphic, :foreign_key]
574
+ INVALID_AUTOMATIC_INVERSE_OPTIONS = [:through, :foreign_key]
517
575
 
518
576
  def add_as_source(seed)
519
577
  seed
@@ -531,32 +589,23 @@ module ActiveRecord
531
589
  Array(options[:extend])
532
590
  end
533
591
 
534
- protected
535
-
536
- def actual_source_reflection # FIXME: this is a horrible name
537
- self
538
- end
539
-
540
592
  private
541
-
542
593
  def calculate_constructable(macro, options)
543
594
  true
544
595
  end
545
596
 
546
597
  # Attempts to find the inverse association name automatically.
547
598
  # If it cannot find a suitable inverse association name, it returns
548
- # nil.
599
+ # +nil+.
549
600
  def inverse_name
550
- options.fetch(:inverse_of) do
551
- if @automatic_inverse_of == false
552
- nil
553
- else
554
- @automatic_inverse_of ||= automatic_inverse_of
555
- end
601
+ unless defined?(@inverse_name)
602
+ @inverse_name = options.fetch(:inverse_of) { automatic_inverse_of }
556
603
  end
604
+
605
+ @inverse_name
557
606
  end
558
607
 
559
- # returns either false or the inverse association name that it finds.
608
+ # returns either +nil+ or the inverse association name that it finds.
560
609
  def automatic_inverse_of
561
610
  if can_find_inverse_of_automatically?(self)
562
611
  inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
@@ -570,23 +619,18 @@ module ActiveRecord
570
619
  end
571
620
 
572
621
  if valid_inverse_reflection?(reflection)
573
- return inverse_name
622
+ inverse_name
574
623
  end
575
624
  end
576
-
577
- false
578
625
  end
579
626
 
580
627
  # Checks if the inverse reflection that is returned from the
581
628
  # +automatic_inverse_of+ method is a valid reflection. We must
582
629
  # make sure that the reflection's active_record name matches up
583
630
  # with the current reflection's klass name.
584
- #
585
- # Note: klass will always be valid because when there's a NameError
586
- # from calling +klass+, +reflection+ will already be set to false.
587
631
  def valid_inverse_reflection?(reflection)
588
632
  reflection &&
589
- klass.name == reflection.active_record.name &&
633
+ klass <= reflection.active_record &&
590
634
  can_find_inverse_of_automatically?(reflection)
591
635
  end
592
636
 
@@ -594,9 +638,8 @@ module ActiveRecord
594
638
  # us from being able to guess the inverse automatically. First, the
595
639
  # <tt>inverse_of</tt> option cannot be set to false. Second, we must
596
640
  # have <tt>has_many</tt>, <tt>has_one</tt>, <tt>belongs_to</tt> associations.
597
- # Third, we must not have options such as <tt>:polymorphic</tt> or
598
- # <tt>:foreign_key</tt> which prevent us from correctly guessing the
599
- # inverse association.
641
+ # Third, we must not have options such as <tt>:foreign_key</tt>
642
+ # which prevent us from correctly guessing the inverse association.
600
643
  #
601
644
  # Anything with a scope can additionally ruin our attempt at finding an
602
645
  # inverse, so we exclude reflections with scopes.
@@ -626,10 +669,6 @@ module ActiveRecord
626
669
  def derive_join_table
627
670
  ModelSchema.derive_join_table_name active_record.table_name, klass.table_name
628
671
  end
629
-
630
- def primary_key(klass)
631
- klass.primary_key || raise(UnknownPrimaryKey.new(klass))
632
- end
633
672
  end
634
673
 
635
674
  class HasManyReflection < AssociationReflection # :nodoc:
@@ -664,7 +703,6 @@ module ActiveRecord
664
703
  end
665
704
 
666
705
  private
667
-
668
706
  def calculate_constructable(macro, options)
669
707
  !options[:through]
670
708
  end
@@ -683,16 +721,18 @@ module ActiveRecord
683
721
  end
684
722
  end
685
723
 
686
- def join_keys(association_klass)
687
- key = polymorphic? ? association_primary_key(association_klass) : association_primary_key
688
- JoinKeys.new(key, foreign_key)
724
+ def join_primary_key(klass = nil)
725
+ polymorphic? ? association_primary_key(klass) : association_primary_key
689
726
  end
690
727
 
691
- def join_id_for(owner) # :nodoc:
692
- owner[foreign_key]
728
+ def join_foreign_key
729
+ foreign_key
693
730
  end
694
731
 
695
732
  private
733
+ def can_find_inverse_of_automatically?(_)
734
+ !polymorphic? && super
735
+ end
696
736
 
697
737
  def calculate_constructable(macro, options)
698
738
  !polymorphic?
@@ -700,10 +740,6 @@ module ActiveRecord
700
740
  end
701
741
 
702
742
  class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
703
- def initialize(name, scope, options, active_record)
704
- super
705
- end
706
-
707
743
  def macro; :has_and_belongs_to_many; end
708
744
 
709
745
  def collection?
@@ -711,16 +747,15 @@ module ActiveRecord
711
747
  end
712
748
  end
713
749
 
714
- # Holds all the meta-data about a :through association as it was specified
750
+ # Holds all the metadata about a :through association as it was specified
715
751
  # in the Active Record class.
716
752
  class ThroughReflection < AbstractReflection #:nodoc:
717
- attr_reader :delegate_reflection
718
- delegate :foreign_key, :foreign_type, :association_foreign_key,
719
- :active_record_primary_key, :type, :to => :source_reflection
753
+ delegate :foreign_key, :foreign_type, :association_foreign_key, :join_id_for,
754
+ :active_record_primary_key, :type, :get_join_keys, to: :source_reflection
720
755
 
721
756
  def initialize(delegate_reflection)
722
757
  @delegate_reflection = delegate_reflection
723
- @klass = delegate_reflection.options[:anonymous_class]
758
+ @klass = delegate_reflection.options[:anonymous_class]
724
759
  @source_reflection_name = delegate_reflection.options[:source]
725
760
  end
726
761
 
@@ -798,45 +833,12 @@ module ActiveRecord
798
833
  through_reflection.clear_association_scope_cache
799
834
  end
800
835
 
801
- # Consider the following example:
802
- #
803
- # class Person
804
- # has_many :articles
805
- # has_many :comment_tags, through: :articles
806
- # end
807
- #
808
- # class Article
809
- # has_many :comments
810
- # has_many :comment_tags, through: :comments, source: :tags
811
- # end
812
- #
813
- # class Comment
814
- # has_many :tags
815
- # end
816
- #
817
- # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags,
818
- # but only Comment.tags will be represented in the #chain. So this method creates an array
819
- # of scopes corresponding to the chain.
820
- def scope_chain
821
- @scope_chain ||= begin
822
- scope_chain = source_reflection.scope_chain.map(&:dup)
823
-
824
- # Add to it the scope from this reflection (if any)
825
- scope_chain.first << scope if scope
826
-
827
- through_scope_chain = through_reflection.scope_chain.map(&:dup)
828
-
829
- if options[:source_type]
830
- type = foreign_type
831
- source_type = options[:source_type]
832
- through_scope_chain.first << lambda { |object|
833
- where(type => source_type)
834
- }
835
- end
836
+ def scopes
837
+ source_reflection.scopes + super
838
+ end
836
839
 
837
- # Recursively fill out the rest of the array from the through reflection
838
- scope_chain + through_scope_chain
839
- end
840
+ def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
841
+ source_reflection.join_scopes(table, predicate_builder, klass) + super
840
842
  end
841
843
 
842
844
  def has_scope?
@@ -845,10 +847,6 @@ module ActiveRecord
845
847
  through_reflection.has_scope?
846
848
  end
847
849
 
848
- def join_keys(association_klass)
849
- source_reflection.join_keys(association_klass)
850
- end
851
-
852
850
  # A through association is nested if there would be more than one join table
853
851
  def nested?
854
852
  source_reflection.through_reflection? || through_reflection.through_reflection?
@@ -863,10 +861,6 @@ module ActiveRecord
863
861
  actual_source_reflection.options[:primary_key] || primary_key(klass || self.klass)
864
862
  end
865
863
 
866
- def association_primary_key_type
867
- klass.type_for_attribute(association_primary_key.to_s)
868
- end
869
-
870
864
  # Gets an array of possible <tt>:through</tt> source reflection names in both singular and plural form.
871
865
  #
872
866
  # class Post < ActiveRecord::Base
@@ -891,15 +885,13 @@ module ActiveRecord
891
885
  }
892
886
 
893
887
  if names.length > 1
894
- example_options = options.dup
895
- example_options[:source] = source_reflection_names.first
896
- ActiveSupport::Deprecation.warn \
897
- "Ambiguous source reflection for through association. Please " \
898
- "specify a :source directive on your declaration like:\n" \
899
- "\n" \
900
- " class #{active_record.name} < ActiveRecord::Base\n" \
901
- " #{macro} :#{name}, #{example_options}\n" \
902
- " end"
888
+ raise AmbiguousSourceReflectionForThroughAssociation.new(
889
+ active_record.name,
890
+ macro,
891
+ name,
892
+ options,
893
+ source_reflection_names
894
+ )
903
895
  end
904
896
 
905
897
  @source_reflection_name = names.first
@@ -913,10 +905,6 @@ module ActiveRecord
913
905
  through_reflection.options
914
906
  end
915
907
 
916
- def join_id_for(owner) # :nodoc:
917
- source_reflection.join_id_for(owner)
918
- end
919
-
920
908
  def check_validity!
921
909
  if through_reflection.nil?
922
910
  raise HasManyThroughAssociationNotFoundError.new(active_record.name, self)
@@ -946,6 +934,14 @@ module ActiveRecord
946
934
  raise HasOneThroughCantAssociateThroughCollection.new(active_record.name, self, through_reflection)
947
935
  end
948
936
 
937
+ if parent_reflection.nil?
938
+ reflections = active_record.reflections.keys.map(&:to_sym)
939
+
940
+ if reflections.index(through_reflection.name) > reflections.index(name)
941
+ raise HasManyThroughOrderError.new(active_record.name, self, through_reflection)
942
+ end
943
+ end
944
+
949
945
  check_validity_of_inverse!
950
946
  end
951
947
 
@@ -967,28 +963,25 @@ module ActiveRecord
967
963
  collect_join_reflections(seed + [self])
968
964
  end
969
965
 
970
- def collect_join_reflections(seed)
971
- a = source_reflection.add_as_source seed
972
- if options[:source_type]
973
- through_reflection.add_as_polymorphic_through self, a
974
- else
975
- through_reflection.add_as_through a
976
- end
977
- end
978
-
979
966
  protected
980
-
981
967
  def actual_source_reflection # FIXME: this is a horrible name
982
- source_reflection.send(:actual_source_reflection)
968
+ source_reflection.actual_source_reflection
983
969
  end
984
970
 
985
- def primary_key(klass)
986
- klass.primary_key || raise(UnknownPrimaryKey.new(klass))
971
+ private
972
+ attr_reader :delegate_reflection
973
+
974
+ def collect_join_reflections(seed)
975
+ a = source_reflection.add_as_source seed
976
+ if options[:source_type]
977
+ through_reflection.add_as_polymorphic_through self, a
978
+ else
979
+ through_reflection.add_as_through a
980
+ end
987
981
  end
988
982
 
989
983
  def inverse_name; delegate_reflection.send(:inverse_name); end
990
984
 
991
- private
992
985
  def derive_class_name
993
986
  # get the class_name of the belongs_to association of the through reflection
994
987
  options[:source_type] || source_reflection.class_name
@@ -998,52 +991,35 @@ module ActiveRecord
998
991
  public_instance_methods
999
992
 
1000
993
  delegate(*delegate_methods, to: :delegate_reflection)
1001
-
1002
994
  end
1003
995
 
1004
- class PolymorphicReflection < ThroughReflection # :nodoc:
996
+ class PolymorphicReflection < AbstractReflection # :nodoc:
997
+ delegate :klass, :scope, :plural_name, :type, :get_join_keys, :scope_for, to: :@reflection
998
+
1005
999
  def initialize(reflection, previous_reflection)
1006
1000
  @reflection = reflection
1007
1001
  @previous_reflection = previous_reflection
1008
1002
  end
1009
1003
 
1010
- def klass
1011
- @reflection.klass
1012
- end
1013
-
1014
- def scope
1015
- @reflection.scope
1016
- end
1017
-
1018
- def table_name
1019
- @reflection.table_name
1020
- end
1021
-
1022
- def plural_name
1023
- @reflection.plural_name
1024
- end
1025
-
1026
- def join_keys(association_klass)
1027
- @reflection.join_keys(association_klass)
1028
- end
1029
-
1030
- def type
1031
- @reflection.type
1004
+ def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
1005
+ scopes = @previous_reflection.join_scopes(table, predicate_builder) + super
1006
+ scopes << build_scope(table, predicate_builder, klass).instance_exec(nil, &source_type_scope)
1032
1007
  end
1033
1008
 
1034
1009
  def constraints
1035
- @reflection.constraints + [source_type_info]
1010
+ @reflection.constraints + [source_type_scope]
1036
1011
  end
1037
1012
 
1038
- def source_type_info
1039
- type = @previous_reflection.foreign_type
1040
- source_type = @previous_reflection.options[:source_type]
1041
- lambda { |object| where(type => source_type) }
1042
- end
1013
+ private
1014
+ def source_type_scope
1015
+ type = @previous_reflection.foreign_type
1016
+ source_type = @previous_reflection.options[:source_type]
1017
+ lambda { |object| where(type => source_type) }
1018
+ end
1043
1019
  end
1044
1020
 
1045
- class RuntimeReflection < PolymorphicReflection # :nodoc:
1046
- attr_accessor :next
1021
+ class RuntimeReflection < AbstractReflection # :nodoc:
1022
+ delegate :scope, :type, :constraints, :get_join_keys, to: :@reflection
1047
1023
 
1048
1024
  def initialize(reflection, association)
1049
1025
  @reflection = reflection
@@ -1054,24 +1030,8 @@ module ActiveRecord
1054
1030
  @association.klass
1055
1031
  end
1056
1032
 
1057
- def table_name
1058
- klass.table_name
1059
- end
1060
-
1061
- def constraints
1062
- @reflection.constraints
1063
- end
1064
-
1065
- def source_type_info
1066
- @reflection.source_type_info
1067
- end
1068
-
1069
- def alias_candidate(name)
1070
- "#{plural_name}_#{name}_join"
1071
- end
1072
-
1073
- def alias_name
1074
- Arel::Table.new(table_name)
1033
+ def aliased_table
1034
+ @aliased_table ||= Arel::Table.new(table_name, type_caster: klass.type_caster)
1075
1035
  end
1076
1036
 
1077
1037
  def all_includes; yield; end