activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  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 +8 -6
  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 +14 -19
  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/interval.rb +49 -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 +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  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_decorators.rb +0 -66
  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/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  # = Active Record Association Collection
@@ -10,9 +12,9 @@ module ActiveRecord
10
12
  # HasManyAssociation => has_many
11
13
  # HasManyThroughAssociation + ThroughAssociation => has_many :through
12
14
  #
13
- # CollectionAssociation class provides common methods to the collections
15
+ # The CollectionAssociation class provides common methods to the collections
14
16
  # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
15
- # +:through association+ option.
17
+ # the +:through association+ option.
16
18
  #
17
19
  # You need to be careful with assumptions regarding the target: The proxy
18
20
  # does not fetch records from the database until it needs them, but new
@@ -24,22 +26,14 @@ module ActiveRecord
24
26
  # If you need to work on all current children, new and existing records,
25
27
  # +load_target+ and the +loaded+ flag are your friends.
26
28
  class CollectionAssociation < Association #:nodoc:
27
-
28
29
  # Implements the reader method, e.g. foo.items for Foo.has_many :items
29
- def reader(force_reload = false)
30
- if force_reload
31
- klass.uncached { reload }
32
- elsif stale_target?
30
+ def reader
31
+ if stale_target?
33
32
  reload
34
33
  end
35
34
 
36
- if owner.new_record?
37
- # Cache the proxy separately before the owner has an id
38
- # or else a post-save proxy will still lack the id
39
- @new_record_proxy ||= CollectionProxy.create(klass, self)
40
- else
41
- @proxy ||= CollectionProxy.create(klass, self)
42
- end
35
+ @proxy ||= CollectionProxy.create(klass, self)
36
+ @proxy.reset_scope
43
37
  end
44
38
 
45
39
  # Implements the writer method, e.g. foo.items= for Foo.has_many :items
@@ -50,128 +44,75 @@ module ActiveRecord
50
44
  # Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
51
45
  def ids_reader
52
46
  if loaded?
53
- load_target.map do |record|
54
- record.send(reflection.association_primary_key)
55
- end
47
+ target.pluck(reflection.association_primary_key)
48
+ elsif !target.empty?
49
+ load_target.pluck(reflection.association_primary_key)
56
50
  else
57
- column = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
58
- scope.pluck(column)
51
+ @association_ids ||= scope.pluck(reflection.association_primary_key)
59
52
  end
60
53
  end
61
54
 
62
55
  # Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
63
56
  def ids_writer(ids)
64
- pk_column = reflection.association_primary_key
65
- pk_type = klass.type_for_attribute(pk_column)
66
- ids = Array(ids).reject(&:blank?).map do |i|
67
- pk_type.type_cast_from_user(i)
68
- end
57
+ primary_key = reflection.association_primary_key
58
+ pk_type = klass.type_for_attribute(primary_key)
59
+ ids = Array(ids).compact_blank
60
+ ids.map! { |i| pk_type.cast(i) }
69
61
 
70
- objs = klass.where(pk_column => ids).index_by do |r|
71
- r.send(pk_column)
62
+ records = klass.where(primary_key => ids).index_by do |r|
63
+ r.public_send(primary_key)
72
64
  end.values_at(*ids).compact
73
65
 
74
- if objs.size == ids.size
75
- replace(objs.index_by { |r| r.send(pk_column) }.values_at(*ids))
66
+ if records.size != ids.size
67
+ found_ids = records.map { |record| record.public_send(primary_key) }
68
+ not_found_ids = ids - found_ids
69
+ klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
76
70
  else
77
- klass.all.raise_record_not_found_exception!(ids, objs.size, ids.size)
71
+ replace(records)
78
72
  end
79
73
  end
80
74
 
81
75
  def reset
82
76
  super
83
77
  @target = []
84
- end
85
-
86
- def select(*fields)
87
- if block_given?
88
- load_target.select.each { |e| yield e }
89
- else
90
- scope.select(*fields)
91
- end
78
+ @association_ids = nil
92
79
  end
93
80
 
94
81
  def find(*args)
95
- if block_given?
96
- load_target.find(*args) { |*block_args| yield(*block_args) }
97
- else
98
- if options[:inverse_of] && loaded?
99
- args_flatten = args.flatten
100
- raise RecordNotFound, "Couldn't find #{scope.klass.name} without an ID" if args_flatten.blank?
101
- result = find_by_scan(*args)
102
-
103
- result_size = Array(result).size
104
- if !result || result_size != args_flatten.size
105
- scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size)
106
- else
107
- result
108
- end
109
- else
110
- scope.find(*args)
111
- end
112
- end
113
- end
114
-
115
- def first(*args)
116
- first_nth_or_last(:first, *args)
117
- end
118
-
119
- def second(*args)
120
- first_nth_or_last(:second, *args)
121
- end
122
-
123
- def third(*args)
124
- first_nth_or_last(:third, *args)
125
- end
126
-
127
- def fourth(*args)
128
- first_nth_or_last(:fourth, *args)
129
- end
130
-
131
- def fifth(*args)
132
- first_nth_or_last(:fifth, *args)
133
- end
82
+ if options[:inverse_of] && loaded?
83
+ args_flatten = args.flatten
84
+ model = scope.klass
134
85
 
135
- def forty_two(*args)
136
- first_nth_or_last(:forty_two, *args)
137
- end
86
+ if args_flatten.blank?
87
+ error_message = "Couldn't find #{model.name} without an ID"
88
+ raise RecordNotFound.new(error_message, model.name, model.primary_key, args)
89
+ end
138
90
 
139
- def last(*args)
140
- first_nth_or_last(:last, *args)
141
- end
91
+ result = find_by_scan(*args)
142
92
 
143
- def take(n = nil)
144
- if loaded?
145
- n ? target.take(n) : target.first
146
- else
147
- scope.take(n).tap do |record|
148
- set_inverse_instance record if record.is_a? ActiveRecord::Base
93
+ result_size = Array(result).size
94
+ if !result || result_size != args_flatten.size
95
+ scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size)
96
+ else
97
+ result
149
98
  end
99
+ else
100
+ scope.find(*args)
150
101
  end
151
102
  end
152
103
 
153
- def build(attributes = {}, &block)
104
+ def build(attributes = nil, &block)
154
105
  if attributes.is_a?(Array)
155
106
  attributes.collect { |attr| build(attr, &block) }
156
107
  else
157
- add_to_target(build_record(attributes)) do |record|
158
- yield(record) if block_given?
159
- end
108
+ add_to_target(build_record(attributes, &block), replace: true)
160
109
  end
161
110
  end
162
111
 
163
- def create(attributes = {}, &block)
164
- _create_record(attributes, &block)
165
- end
166
-
167
- def create!(attributes = {}, &block)
168
- _create_record(attributes, true, &block)
169
- end
170
-
171
- # Add +records+ to this association. Returns +self+ so method calls may
172
- # be chained. Since << flattens its argument list and inserts each record,
173
- # +push+ and +concat+ behave identically.
112
+ # Add +records+ to this association. Since +<<+ flattens its argument list
113
+ # and inserts each record, +push+ and +concat+ behave identically.
174
114
  def concat(*records)
115
+ records = records.flatten
175
116
  if owner.new_record?
176
117
  load_target
177
118
  concat_records(records)
@@ -214,12 +155,12 @@ module ActiveRecord
214
155
  end
215
156
 
216
157
  dependent = if dependent
217
- dependent
218
- elsif options[:dependent] == :destroy
219
- :delete_all
220
- else
221
- options[:dependent]
222
- end
158
+ dependent
159
+ elsif options[:dependent] == :destroy
160
+ :delete_all
161
+ else
162
+ options[:dependent]
163
+ end
223
164
 
224
165
  delete_or_nullify_all_records(dependent).tap do
225
166
  reset
@@ -237,32 +178,6 @@ module ActiveRecord
237
178
  end
238
179
  end
239
180
 
240
- # Count all records using SQL. Construct options and pass them with
241
- # scope to the target class's +count+.
242
- def count(column_name = nil, count_options = {})
243
- # TODO: Remove count_options argument as soon we remove support to
244
- # activerecord-deprecated_finders.
245
- column_name, count_options = nil, column_name if column_name.is_a?(Hash)
246
-
247
- relation = scope
248
- if association_scope.distinct_value
249
- # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL.
250
- column_name ||= reflection.klass.primary_key
251
- relation = relation.distinct
252
- end
253
-
254
- value = relation.count(column_name)
255
-
256
- limit = options[:limit]
257
- offset = options[:offset]
258
-
259
- if limit || offset
260
- [ [value - offset.to_i, 0].max, limit.to_i ].min
261
- else
262
- value
263
- end
264
- end
265
-
266
181
  # Removes +records+ from this association calling +before_remove+ and
267
182
  # +after_remove+ callbacks.
268
183
  #
@@ -271,12 +186,7 @@ module ActiveRecord
271
186
  # are actually removed from the database, that depends precisely on
272
187
  # +delete_records+. They are in any case removed from the collection.
273
188
  def delete(*records)
274
- return if records.empty?
275
- _options = records.extract_options!
276
- dependent = _options[:dependent] || options[:dependent]
277
-
278
- records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
279
- delete_or_destroy(records, dependent)
189
+ delete_or_destroy(records, options[:dependent])
280
190
  end
281
191
 
282
192
  # Deletes the +records+ and removes them from this association calling
@@ -285,8 +195,6 @@ module ActiveRecord
285
195
  # Note that this method removes records from the database ignoring the
286
196
  # +:dependent+ option.
287
197
  def destroy(*records)
288
- return if records.empty?
289
- records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
290
198
  delete_or_destroy(records, :destroy)
291
199
  end
292
200
 
@@ -302,73 +210,34 @@ module ActiveRecord
302
210
  # +count_records+, which is a method descendants have to provide.
303
211
  def size
304
212
  if !find_target? || loaded?
305
- if association_scope.distinct_value
306
- target.uniq.size
307
- else
308
- target.size
309
- end
310
- elsif !loaded? && !association_scope.group_values.empty?
213
+ target.size
214
+ elsif @association_ids
215
+ @association_ids.size
216
+ elsif !association_scope.group_values.empty?
311
217
  load_target.size
312
- elsif !loaded? && !association_scope.distinct_value && target.is_a?(Array)
313
- unsaved_records = target.select { |r| r.new_record? }
218
+ elsif !association_scope.distinct_value && !target.empty?
219
+ unsaved_records = target.select(&:new_record?)
314
220
  unsaved_records.size + count_records
315
221
  else
316
222
  count_records
317
223
  end
318
224
  end
319
225
 
320
- # Returns the size of the collection calling +size+ on the target.
321
- #
322
- # If the collection has been already loaded +length+ and +size+ are
323
- # equivalent. If not and you are going to need the records anyway this
324
- # method will take one less query. Otherwise +size+ is more efficient.
325
- def length
326
- load_target.size
327
- end
328
-
329
226
  # Returns true if the collection is empty.
330
227
  #
331
228
  # If the collection has been loaded
332
229
  # it is equivalent to <tt>collection.size.zero?</tt>. If the
333
230
  # collection has not been loaded, it is equivalent to
334
- # <tt>collection.exists?</tt>. If the collection has not already been
231
+ # <tt>!collection.exists?</tt>. If the collection has not already been
335
232
  # loaded and you are going to fetch the records anyway it is better to
336
233
  # check <tt>collection.length.zero?</tt>.
337
234
  def empty?
338
- if loaded?
235
+ if loaded? || @association_ids || reflection.has_cached_counter?
339
236
  size.zero?
340
237
  else
341
- @target.blank? && !scope.exists?
342
- end
343
- end
344
-
345
- # Returns true if the collections is not empty.
346
- # Equivalent to +!collection.empty?+.
347
- def any?
348
- if block_given?
349
- load_target.any? { |*block_args| yield(*block_args) }
350
- else
351
- !empty?
352
- end
353
- end
354
-
355
- # Returns true if the collection has more than 1 record.
356
- # Equivalent to +collection.size > 1+.
357
- def many?
358
- if block_given?
359
- load_target.many? { |*block_args| yield(*block_args) }
360
- else
361
- size > 1
362
- end
363
- end
364
-
365
- def distinct
366
- seen = {}
367
- load_target.find_all do |record|
368
- seen[record.id] = true unless seen.key?(record.id)
238
+ target.empty? && !scope.exists?
369
239
  end
370
240
  end
371
- alias uniq distinct
372
241
 
373
242
  # Replace this collection with +other_array+. This will perform a diff
374
243
  # and delete/add only records that have changed.
@@ -382,6 +251,8 @@ module ActiveRecord
382
251
  replace_common_records_in_memory(other_array, original_target)
383
252
  if other_array != original_target
384
253
  transaction { replace_records(other_array, original_target) }
254
+ else
255
+ other_array
385
256
  end
386
257
  end
387
258
  end
@@ -407,32 +278,27 @@ module ActiveRecord
407
278
  target
408
279
  end
409
280
 
410
- def add_to_target(record, skip_callbacks = false, &block)
411
- if association_scope.distinct_value
281
+ def add_to_target(record, skip_callbacks: false, replace: false, &block)
282
+ if replace || association_scope.distinct_value
412
283
  index = @target.index(record)
413
284
  end
414
285
  replace_on_target(record, index, skip_callbacks, &block)
415
286
  end
416
287
 
417
- def replace_on_target(record, index, skip_callbacks)
418
- callback(:before_add, record) unless skip_callbacks
419
- yield(record) if block_given?
288
+ def target=(record)
289
+ return super unless ActiveRecord::Base.has_many_inversing
420
290
 
421
- if index
422
- @target[index] = record
291
+ case record
292
+ when Array
293
+ super
423
294
  else
424
- @target << record
295
+ add_to_target(record, skip_callbacks: true, replace: true)
425
296
  end
426
-
427
- callback(:after_add, record) unless skip_callbacks
428
- set_inverse_instance(record)
429
-
430
- record
431
297
  end
432
298
 
433
- def scope(opts = {})
434
- scope = super()
435
- scope.none! if opts.fetch(:nullify, true) && null_scope?
299
+ def scope
300
+ scope = super
301
+ scope.none! if null_scope?
436
302
  scope
437
303
  end
438
304
 
@@ -440,28 +306,15 @@ module ActiveRecord
440
306
  owner.new_record? && !foreign_key_present?
441
307
  end
442
308
 
443
- private
444
- def get_records
445
- return scope.to_a if skip_statement_cache?
446
-
447
- conn = klass.connection
448
- sc = reflection.association_scope_cache(conn, owner) do
449
- StatementCache.create(conn) { |params|
450
- as = AssociationScope.create { params.bind }
451
- target_scope.merge as.scope(self, conn)
452
- }
453
- end
454
-
455
- binds = AssociationScope.get_bind_values(owner, reflection.chain)
456
- sc.execute binds, klass, klass.connection
309
+ def find_from_target?
310
+ loaded? ||
311
+ owner.strict_loading? ||
312
+ reflection.strict_loading? ||
313
+ owner.new_record? ||
314
+ target.any? { |record| record.new_record? || record.changed? }
457
315
  end
458
316
 
459
- def find_target
460
- records = get_records
461
- records.each { |record| set_inverse_instance(record) }
462
- records
463
- end
464
-
317
+ private
465
318
  # We have some records loaded from the database (persisted) and some that are
466
319
  # in-memory (memory). The same record may be represented in the persisted array
467
320
  # and in the memory array.
@@ -479,7 +332,7 @@ module ActiveRecord
479
332
  persisted.map! do |record|
480
333
  if mem_record = memory.delete(record)
481
334
 
482
- ((record.attribute_names & mem_record.attribute_names) - mem_record.changes.keys).each do |name|
335
+ ((record.attribute_names & mem_record.attribute_names) - mem_record.changed_attribute_names_to_save).each do |name|
483
336
  mem_record[name] = record[name]
484
337
  end
485
338
 
@@ -500,28 +353,35 @@ module ActiveRecord
500
353
  if attributes.is_a?(Array)
501
354
  attributes.collect { |attr| _create_record(attr, raise, &block) }
502
355
  else
356
+ record = build_record(attributes, &block)
503
357
  transaction do
504
- add_to_target(build_record(attributes)) do |record|
505
- yield(record) if block_given?
506
- insert_record(record, true, raise)
358
+ result = nil
359
+ add_to_target(record) do
360
+ result = insert_record(record, true, raise) {
361
+ @_was_loaded = loaded?
362
+ }
507
363
  end
364
+ raise ActiveRecord::Rollback unless result
508
365
  end
366
+ record
509
367
  end
510
368
  end
511
369
 
512
370
  # Do the relevant stuff to insert the given record into the association collection.
513
- def insert_record(record, validate = true, raise = false)
514
- raise NotImplementedError
515
- end
516
-
517
- def create_scope
518
- scope.scope_for_create.stringify_keys
371
+ def insert_record(record, validate = true, raise = false, &block)
372
+ if raise
373
+ record.save!(validate: validate, &block)
374
+ else
375
+ record.save(validate: validate, &block)
376
+ end
519
377
  end
520
378
 
521
379
  def delete_or_destroy(records, method)
380
+ return if records.empty?
381
+ records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
522
382
  records = records.flatten
523
383
  records.each { |record| raise_on_type_mismatch!(record) }
524
- existing_records = records.reject { |r| r.new_record? }
384
+ existing_records = records.reject(&:new_record?)
525
385
 
526
386
  if existing_records.empty?
527
387
  remove_records(existing_records, records, method)
@@ -531,24 +391,28 @@ module ActiveRecord
531
391
  end
532
392
 
533
393
  def remove_records(existing_records, records, method)
534
- records.each { |record| callback(:before_remove, record) }
394
+ catch(:abort) do
395
+ records.each { |record| callback(:before_remove, record) }
396
+ end || return
535
397
 
536
398
  delete_records(existing_records, method) if existing_records.any?
537
- records.each { |record| target.delete(record) }
399
+ @target -= records
400
+ @association_ids = nil
538
401
 
539
402
  records.each { |record| callback(:after_remove, record) }
540
403
  end
541
404
 
542
- # Delete the given records from the association, using one of the methods :destroy,
543
- # :delete_all or :nullify (or nil, in which case a default is used).
405
+ # Delete the given records from the association,
406
+ # using one of the methods +:destroy+, +:delete_all+
407
+ # or +:nullify+ (or +nil+, in which case a default is used).
544
408
  def delete_records(records, method)
545
409
  raise NotImplementedError
546
410
  end
547
411
 
548
412
  def replace_records(new_target, original_target)
549
- delete(target - new_target)
413
+ delete(difference(target, new_target))
550
414
 
551
- unless concat(new_target - target)
415
+ unless concat(difference(new_target, target))
552
416
  @target = original_target
553
417
  raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
554
418
  "new records could not be saved."
@@ -558,24 +422,55 @@ module ActiveRecord
558
422
  end
559
423
 
560
424
  def replace_common_records_in_memory(new_target, original_target)
561
- common_records = new_target & original_target
425
+ common_records = intersection(new_target, original_target)
562
426
  common_records.each do |record|
563
427
  skip_callbacks = true
564
428
  replace_on_target(record, @target.index(record), skip_callbacks)
565
429
  end
566
430
  end
567
431
 
568
- def concat_records(records, should_raise = false)
432
+ def concat_records(records, raise = false)
569
433
  result = true
570
434
 
571
- records.flatten.each do |record|
435
+ records.each do |record|
572
436
  raise_on_type_mismatch!(record)
573
- add_to_target(record) do |rec|
574
- result &&= insert_record(rec, true, should_raise) unless owner.new_record?
437
+ add_to_target(record) do
438
+ unless owner.new_record?
439
+ result &&= insert_record(record, true, raise) {
440
+ @_was_loaded = loaded?
441
+ }
442
+ end
575
443
  end
576
444
  end
577
445
 
578
- result && records
446
+ raise ActiveRecord::Rollback unless result
447
+
448
+ records
449
+ end
450
+
451
+ def replace_on_target(record, index, skip_callbacks)
452
+ catch(:abort) do
453
+ callback(:before_add, record)
454
+ end || return unless skip_callbacks
455
+
456
+ set_inverse_instance(record)
457
+
458
+ @_was_loaded = true
459
+
460
+ yield(record) if block_given?
461
+
462
+ if index
463
+ target[index] = record
464
+ elsif @_was_loaded || !loaded?
465
+ @association_ids = nil
466
+ target << record
467
+ end
468
+
469
+ callback(:after_add, record) unless skip_callbacks
470
+
471
+ record
472
+ ensure
473
+ @_was_loaded = nil
579
474
  end
580
475
 
581
476
  def callback(method, record)
@@ -589,36 +484,12 @@ module ActiveRecord
589
484
  owner.class.send(full_callback_name)
590
485
  end
591
486
 
592
- # Should we deal with assoc.first or assoc.last by issuing an independent query to
593
- # the database, or by getting the target, and then taking the first/last item from that?
594
- #
595
- # If the args is just a non-empty options hash, go to the database.
596
- #
597
- # Otherwise, go to the database only if none of the following are true:
598
- # * target already loaded
599
- # * owner is new record
600
- # * target contains new or changed record(s)
601
- def fetch_first_nth_or_last_using_find?(args)
602
- if args.first.is_a?(Hash)
603
- true
604
- else
605
- !(loaded? ||
606
- owner.new_record? ||
607
- target.any? { |record| record.new_record? || record.changed? })
608
- end
609
- end
610
-
611
487
  def include_in_memory?(record)
612
488
  if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
613
489
  assoc = owner.association(reflection.through_reflection.name)
614
490
  assoc.reader.any? { |source|
615
- target_association = source.send(reflection.source_reflection.name)
616
-
617
- if target_association.respond_to?(:include?)
618
- target_association.include?(record)
619
- else
620
- target_association == record
621
- end
491
+ target_reflection = source.send(reflection.source_reflection.name)
492
+ target_reflection.respond_to?(:include?) ? target_reflection.include?(record) : target_reflection == record
622
493
  } || target.include?(record)
623
494
  else
624
495
  target.include?(record)
@@ -629,7 +500,7 @@ module ActiveRecord
629
500
  # specified, then #find scans the entire collection.
630
501
  def find_by_scan(*args)
631
502
  expects_array = args.first.kind_of?(Array)
632
- ids = args.flatten.compact.map{ |arg| arg.to_s }.uniq
503
+ ids = args.flatten.compact.map(&:to_s).uniq
633
504
 
634
505
  if ids.size == 1
635
506
  id = ids.first
@@ -639,16 +510,6 @@ module ActiveRecord
639
510
  load_target.select { |r| ids.include?(r.id.to_s) }
640
511
  end
641
512
  end
642
-
643
- # Fetches the first/last using SQL if possible, otherwise from the target array.
644
- def first_nth_or_last(type, *args)
645
- args.shift if args.first.is_a?(Hash) && args.first.empty?
646
-
647
- collection = fetch_first_nth_or_last_using_find?(args) ? scope : load_target
648
- collection.send(type, *args).tap do |record|
649
- set_inverse_instance record if record.is_a? ActiveRecord::Base
650
- end
651
- end
652
513
  end
653
514
  end
654
515
  end