activerecord 4.2.0 → 6.0.0

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

Potentially problematic release.


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

Files changed (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -971
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -248
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +135 -56
  11. data/lib/active_record/associations/association_scope.rb +103 -131
  12. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +27 -40
  15. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  16. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
  18. data/lib/active_record/associations/builder/has_many.rb +8 -4
  19. data/lib/active_record/associations/builder/has_one.rb +46 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +138 -274
  22. data/lib/active_record/associations/collection_proxy.rb +252 -151
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -83
  25. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  26. data/lib/active_record/associations/has_one_association.rb +62 -49
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
  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 +138 -162
  32. data/lib/active_record/associations/preloader/association.rb +90 -119
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +92 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1737 -1596
  38. data/lib/active_record/attribute_assignment.rb +56 -183
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  42. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  43. data/lib/active_record/attribute_methods/query.rb +6 -5
  44. data/lib/active_record/attribute_methods/read.rb +20 -76
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +33 -55
  48. data/lib/active_record/attribute_methods.rb +124 -143
  49. data/lib/active_record/attributes.rb +214 -74
  50. data/lib/active_record/autosave_association.rb +115 -46
  51. data/lib/active_record/base.rb +60 -49
  52. data/lib/active_record/callbacks.rb +100 -74
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
  68. data/lib/active_record/connection_adapters/column.rb +56 -43
  69. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  98. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
  116. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +288 -359
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +176 -41
  128. data/lib/active_record/core.rb +266 -233
  129. data/lib/active_record/counter_cache.rb +68 -50
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -105
  136. data/lib/active_record/enum.rb +164 -88
  137. data/lib/active_record/errors.rb +189 -53
  138. data/lib/active_record/explain.rb +23 -11
  139. data/lib/active_record/explain_registry.rb +4 -2
  140. data/lib/active_record/explain_subscriber.rb +11 -6
  141. data/lib/active_record/fixture_set/file.rb +35 -9
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +226 -495
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +158 -112
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +123 -29
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +3 -2
  154. data/lib/active_record/locking/optimistic.rb +91 -98
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +76 -33
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +177 -90
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +8 -6
  163. data/lib/active_record/migration.rb +634 -288
  164. data/lib/active_record/model_schema.rb +314 -112
  165. data/lib/active_record/nested_attributes.rb +266 -214
  166. data/lib/active_record/no_touching.rb +15 -2
  167. data/lib/active_record/null_relation.rb +24 -37
  168. data/lib/active_record/persistence.rb +559 -124
  169. data/lib/active_record/query_cache.rb +19 -23
  170. data/lib/active_record/querying.rb +43 -29
  171. data/lib/active_record/railtie.rb +148 -47
  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 +338 -202
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +460 -299
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +207 -55
  180. data/lib/active_record/relation/calculations.rb +269 -248
  181. data/lib/active_record/relation/delegation.rb +70 -80
  182. data/lib/active_record/relation/finder_methods.rb +279 -255
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +83 -69
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  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 +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  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 +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  192. data/lib/active_record/relation/predicate_builder.rb +116 -92
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +574 -391
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +18 -16
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +518 -340
  200. data/lib/active_record/result.rb +79 -42
  201. data/lib/active_record/runtime_registry.rb +6 -4
  202. data/lib/active_record/sanitization.rb +144 -121
  203. data/lib/active_record/schema.rb +21 -24
  204. data/lib/active_record/schema_dumper.rb +112 -93
  205. data/lib/active_record/schema_migration.rb +24 -20
  206. data/lib/active_record/scoping/default.rb +101 -84
  207. data/lib/active_record/scoping/named.rb +86 -33
  208. data/lib/active_record/scoping.rb +45 -26
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +5 -5
  211. data/lib/active_record/statement_cache.rb +73 -36
  212. data/lib/active_record/store.rb +127 -42
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +309 -99
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +86 -40
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +215 -139
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +4 -41
  227. data/lib/active_record/type/date_time.rb +4 -38
  228. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  229. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +30 -15
  233. data/lib/active_record/type/text.rb +2 -2
  234. data/lib/active_record/type/time.rb +11 -16
  235. data/lib/active_record/type/type_map.rb +15 -17
  236. data/lib/active_record/type/unsigned_integer.rb +9 -7
  237. data/lib/active_record/type.rb +78 -23
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +13 -4
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +14 -13
  245. data/lib/active_record/validations/uniqueness.rb +43 -46
  246. data/lib/active_record/validations.rb +39 -35
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +43 -21
  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 +257 -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 +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -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 +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  335. data/lib/rails/generators/active_record/migration.rb +31 -1
  336. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +166 -60
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_set/builder.rb +0 -86
  349. data/lib/active_record/attribute_set.rb +0 -77
  350. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  351. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  352. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  353. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  354. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  355. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  356. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  357. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  358. data/lib/active_record/type/big_integer.rb +0 -13
  359. data/lib/active_record/type/binary.rb +0 -50
  360. data/lib/active_record/type/boolean.rb +0 -30
  361. data/lib/active_record/type/decimal.rb +0 -40
  362. data/lib/active_record/type/decorator.rb +0 -14
  363. data/lib/active_record/type/float.rb +0 -19
  364. data/lib/active_record/type/integer.rb +0 -55
  365. data/lib/active_record/type/mutable.rb +0 -16
  366. data/lib/active_record/type/numeric.rb +0 -36
  367. data/lib/active_record/type/string.rb +0 -36
  368. data/lib/active_record/type/time_value.rb +0 -38
  369. data/lib/active_record/type/value.rb +0 -101
  370. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  371. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  372. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,10 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
- # Association proxies in Active Record are middlemen between the object that
4
- # holds the association, known as the <tt>@owner</tt>, and the actual associated
5
- # object, known as the <tt>@target</tt>. The kind of association any proxy is
6
- # about is available in <tt>@reflection</tt>. That's an instance of the class
7
- # ActiveRecord::Reflection::AssociationReflection.
5
+ # Collection proxies in Active Record are middlemen between an
6
+ # <tt>association</tt>, and its <tt>target</tt> result set.
8
7
  #
9
8
  # For example, given
10
9
  #
@@ -14,26 +13,26 @@ module ActiveRecord
14
13
  #
15
14
  # blog = Blog.first
16
15
  #
17
- # the association proxy in <tt>blog.posts</tt> has the object in +blog+ as
18
- # <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
19
- # the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
16
+ # The collection proxy returned by <tt>blog.posts</tt> is built from a
17
+ # <tt>:has_many</tt> <tt>association</tt>, and delegates to a collection
18
+ # of posts as the <tt>target</tt>.
20
19
  #
21
- # This class delegates unknown methods to <tt>@target</tt> via
22
- # <tt>method_missing</tt>.
20
+ # This class delegates unknown methods to the <tt>association</tt>'s
21
+ # relation class via a delegate cache.
23
22
  #
24
- # The <tt>@target</tt> object is not \loaded until needed. For example,
23
+ # The <tt>target</tt> result set is not loaded until needed. For example,
25
24
  #
26
25
  # blog.posts.count
27
26
  #
28
27
  # is computed directly through SQL and does not trigger by itself the
29
28
  # instantiation of the actual post records.
30
29
  class CollectionProxy < Relation
31
- delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)
32
-
33
30
  def initialize(klass, association) #:nodoc:
34
31
  @association = association
35
- super klass, klass.arel_table
36
- merge! association.scope(nullify: false)
32
+ super klass
33
+
34
+ extensions = association.extensions
35
+ extend(*extensions) if extensions.any?
37
36
  end
38
37
 
39
38
  def target
@@ -53,6 +52,12 @@ module ActiveRecord
53
52
  @association.loaded?
54
53
  end
55
54
 
55
+ ##
56
+ # :method: select
57
+ #
58
+ # :call-seq:
59
+ # select(*fields, &block)
60
+ #
56
61
  # Works in two ways.
57
62
  #
58
63
  # *First:* Specify a subset of fields to be selected from the result set.
@@ -75,7 +80,7 @@ module ActiveRecord
75
80
  # # #<Pet id: nil, name: "Choo-Choo">
76
81
  # # ]
77
82
  #
78
- # person.pets.select(:id, :name )
83
+ # person.pets.select(:id, :name)
79
84
  # # => [
80
85
  # # #<Pet id: 1, name: "Fancy-Fancy">,
81
86
  # # #<Pet id: 2, name: "Spook">,
@@ -100,18 +105,9 @@ module ActiveRecord
100
105
  # # #<Pet id: 2, name: "Spook", person_id: 1>,
101
106
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
102
107
  # # ]
103
- #
104
- # person.pets.select(:name) { |pet| pet.name =~ /oo/ }
105
- # # => [
106
- # # #<Pet id: 2, name: "Spook">,
107
- # # #<Pet id: 3, name: "Choo-Choo">
108
- # # ]
109
- def select(*fields, &block)
110
- @association.select(*fields, &block)
111
- end
112
108
 
113
109
  # Finds an object in the collection responding to the +id+. Uses the same
114
- # rules as <tt>ActiveRecord::Base.find</tt>. Returns <tt>ActiveRecord::RecordNotFound</tt>
110
+ # rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
115
111
  # error if the object cannot be found.
116
112
  #
117
113
  # class Person < ActiveRecord::Base
@@ -126,7 +122,7 @@ module ActiveRecord
126
122
  # # ]
127
123
  #
128
124
  # person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
129
- # person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=4
125
+ # person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
130
126
  #
131
127
  # person.pets.find(2) { |pet| pet.name.downcase! }
132
128
  # # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
@@ -136,10 +132,17 @@ module ActiveRecord
136
132
  # # #<Pet id: 2, name: "Spook", person_id: 1>,
137
133
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
138
134
  # # ]
139
- def find(*args, &block)
140
- @association.find(*args, &block)
135
+ def find(*args)
136
+ return super if block_given?
137
+ @association.find(*args)
141
138
  end
142
139
 
140
+ ##
141
+ # :method: first
142
+ #
143
+ # :call-seq:
144
+ # first(limit = nil)
145
+ #
143
146
  # Returns the first record, or the first +n+ records, from the collection.
144
147
  # If the collection is empty, the first form returns +nil+, and the second
145
148
  # form returns an empty array.
@@ -166,35 +169,63 @@ module ActiveRecord
166
169
  # another_person_without.pets # => []
167
170
  # another_person_without.pets.first # => nil
168
171
  # another_person_without.pets.first(3) # => []
169
- def first(*args)
170
- @association.first(*args)
171
- end
172
172
 
173
- # Same as +first+ except returns only the second record.
174
- def second(*args)
175
- @association.second(*args)
176
- end
173
+ ##
174
+ # :method: second
175
+ #
176
+ # :call-seq:
177
+ # second()
178
+ #
179
+ # Same as #first except returns only the second record.
177
180
 
178
- # Same as +first+ except returns only the third record.
179
- def third(*args)
180
- @association.third(*args)
181
- end
181
+ ##
182
+ # :method: third
183
+ #
184
+ # :call-seq:
185
+ # third()
186
+ #
187
+ # Same as #first except returns only the third record.
182
188
 
183
- # Same as +first+ except returns only the fourth record.
184
- def fourth(*args)
185
- @association.fourth(*args)
186
- end
189
+ ##
190
+ # :method: fourth
191
+ #
192
+ # :call-seq:
193
+ # fourth()
194
+ #
195
+ # Same as #first except returns only the fourth record.
187
196
 
188
- # Same as +first+ except returns only the fifth record.
189
- def fifth(*args)
190
- @association.fifth(*args)
191
- end
197
+ ##
198
+ # :method: fifth
199
+ #
200
+ # :call-seq:
201
+ # fifth()
202
+ #
203
+ # Same as #first except returns only the fifth record.
192
204
 
193
- # Same as +first+ except returns only the forty second record.
205
+ ##
206
+ # :method: forty_two
207
+ #
208
+ # :call-seq:
209
+ # forty_two()
210
+ #
211
+ # Same as #first except returns only the forty second record.
194
212
  # Also known as accessing "the reddit".
195
- def forty_two(*args)
196
- @association.forty_two(*args)
197
- end
213
+
214
+ ##
215
+ # :method: third_to_last
216
+ #
217
+ # :call-seq:
218
+ # third_to_last()
219
+ #
220
+ # Same as #first except returns only the third-to-last record.
221
+
222
+ ##
223
+ # :method: second_to_last
224
+ #
225
+ # :call-seq:
226
+ # second_to_last()
227
+ #
228
+ # Same as #first except returns only the second-to-last record.
198
229
 
199
230
  # Returns the last record, or the last +n+ records, from the collection.
200
231
  # If the collection is empty, the first form returns +nil+, and the second
@@ -222,8 +253,39 @@ module ActiveRecord
222
253
  # another_person_without.pets # => []
223
254
  # another_person_without.pets.last # => nil
224
255
  # another_person_without.pets.last(3) # => []
225
- def last(*args)
226
- @association.last(*args)
256
+ def last(limit = nil)
257
+ load_target if find_from_target?
258
+ super
259
+ end
260
+
261
+ # Gives a record (or N records if a parameter is supplied) from the collection
262
+ # using the same rules as <tt>ActiveRecord::Base.take</tt>.
263
+ #
264
+ # class Person < ActiveRecord::Base
265
+ # has_many :pets
266
+ # end
267
+ #
268
+ # person.pets
269
+ # # => [
270
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
271
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
272
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
273
+ # # ]
274
+ #
275
+ # person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
276
+ #
277
+ # person.pets.take(2)
278
+ # # => [
279
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
280
+ # # #<Pet id: 2, name: "Spook", person_id: 1>
281
+ # # ]
282
+ #
283
+ # another_person_without.pets # => []
284
+ # another_person_without.pets.take # => nil
285
+ # another_person_without.pets.take(2) # => []
286
+ def take(limit = nil)
287
+ load_target if find_from_target?
288
+ super
227
289
  end
228
290
 
229
291
  # Returns a new object of the collection type that has been instantiated
@@ -285,7 +347,7 @@ module ActiveRecord
285
347
  @association.create(attributes, &block)
286
348
  end
287
349
 
288
- # Like +create+, except that if the record is invalid, raises an exception.
350
+ # Like #create, except that if the record is invalid, raises an exception.
289
351
  #
290
352
  # class Person
291
353
  # has_many :pets
@@ -301,34 +363,6 @@ module ActiveRecord
301
363
  @association.create!(attributes, &block)
302
364
  end
303
365
 
304
- # Add one or more records to the collection by setting their foreign keys
305
- # to the association's primary key. Since << flattens its argument list and
306
- # inserts each record, +push+ and +concat+ behave identically. Returns +self+
307
- # so method calls may be chained.
308
- #
309
- # class Person < ActiveRecord::Base
310
- # has_many :pets
311
- # end
312
- #
313
- # person.pets.size # => 0
314
- # person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
315
- # person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
316
- # person.pets.size # => 3
317
- #
318
- # person.id # => 1
319
- # person.pets
320
- # # => [
321
- # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
322
- # # #<Pet id: 2, name: "Spook", person_id: 1>,
323
- # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
324
- # # ]
325
- #
326
- # person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
327
- # person.pets.size # => 5
328
- def concat(*records)
329
- @association.concat(*records)
330
- end
331
-
332
366
  # Replaces this collection with +other_array+. This will perform a diff
333
367
  # and delete/add only records that have changed.
334
368
  #
@@ -359,7 +393,7 @@ module ActiveRecord
359
393
  # specified by the +:dependent+ option. If no +:dependent+ option is given,
360
394
  # then it will follow the default strategy.
361
395
  #
362
- # For +has_many :through+ associations, the default deletion strategy is
396
+ # For <tt>has_many :through</tt> associations, the default deletion strategy is
363
397
  # +:delete_all+.
364
398
  #
365
399
  # For +has_many+ associations, the default deletion strategy is +:nullify+.
@@ -394,7 +428,7 @@ module ActiveRecord
394
428
  # # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
395
429
  # # ]
396
430
  #
397
- # Both +has_many+ and +has_many :through+ dependencies default to the
431
+ # Both +has_many+ and <tt>has_many :through</tt> dependencies default to the
398
432
  # +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
399
433
  # Records are not instantiated and callbacks will not be fired.
400
434
  #
@@ -413,7 +447,7 @@ module ActiveRecord
413
447
  # person.pets.delete_all
414
448
  #
415
449
  # Pet.find(1, 2, 3)
416
- # # => ActiveRecord::RecordNotFound
450
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
417
451
  #
418
452
  # If it is set to <tt>:delete_all</tt>, all the objects are deleted
419
453
  # *without* calling their +destroy+ method.
@@ -433,9 +467,9 @@ module ActiveRecord
433
467
  # person.pets.delete_all
434
468
  #
435
469
  # Pet.find(1, 2, 3)
436
- # # => ActiveRecord::RecordNotFound
470
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
437
471
  def delete_all(dependent = nil)
438
- @association.delete_all(dependent)
472
+ @association.delete_all(dependent).tap { reset_scope }
439
473
  end
440
474
 
441
475
  # Deletes the records of the collection directly from the database
@@ -462,18 +496,19 @@ module ActiveRecord
462
496
  #
463
497
  # Pet.find(1) # => Couldn't find Pet with id=1
464
498
  def destroy_all
465
- @association.destroy_all
499
+ @association.destroy_all.tap { reset_scope }
466
500
  end
467
501
 
468
- # Deletes the +records+ supplied and removes them from the collection. For
469
- # +has_many+ associations, the deletion is done according to the strategy
470
- # specified by the <tt>:dependent</tt> option. Returns an array with the
502
+ # Deletes the +records+ supplied from the collection according to the strategy
503
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
504
+ # then it will follow the default strategy. Returns an array with the
471
505
  # deleted records.
472
506
  #
473
- # If no <tt>:dependent</tt> option is given, then it will follow the default
474
- # strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign
475
- # keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
476
- # strategy is +delete_all+.
507
+ # For <tt>has_many :through</tt> associations, the default deletion strategy is
508
+ # +:delete_all+.
509
+ #
510
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
511
+ # This sets the foreign keys to +NULL+.
477
512
  #
478
513
  # class Person < ActiveRecord::Base
479
514
  # has_many :pets # dependent: :nullify option by default
@@ -526,7 +561,7 @@ module ActiveRecord
526
561
  # # => [#<Pet id: 2, name: "Spook", person_id: 1>]
527
562
  #
528
563
  # Pet.find(1, 3)
529
- # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 3)
564
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
530
565
  #
531
566
  # If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
532
567
  # *without* calling their +destroy+ method.
@@ -554,9 +589,9 @@ module ActiveRecord
554
589
  # # ]
555
590
  #
556
591
  # Pet.find(1)
557
- # # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
592
+ # # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
558
593
  #
559
- # You can pass +Fixnum+ or +String+ values, it finds the records
594
+ # You can pass +Integer+ or +String+ values, it finds the records
560
595
  # responding to the +id+ and executes delete on them.
561
596
  #
562
597
  # class Person < ActiveRecord::Base
@@ -580,7 +615,7 @@ module ActiveRecord
580
615
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
581
616
  # # ]
582
617
  def delete(*records)
583
- @association.delete(*records)
618
+ @association.delete(*records).tap { reset_scope }
584
619
  end
585
620
 
586
621
  # Destroys the +records+ supplied and removes them from the collection.
@@ -618,9 +653,9 @@ module ActiveRecord
618
653
  # person.pets.size # => 0
619
654
  # person.pets # => []
620
655
  #
621
- # Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 2, 3)
656
+ # Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
622
657
  #
623
- # You can pass +Fixnum+ or +String+ values, it finds the records
658
+ # You can pass +Integer+ or +String+ values, it finds the records
624
659
  # responding to the +id+ and then deletes them from the database.
625
660
  #
626
661
  # person.pets.size # => 3
@@ -650,11 +685,17 @@ module ActiveRecord
650
685
  # person.pets.size # => 0
651
686
  # person.pets # => []
652
687
  #
653
- # Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (4, 5, 6)
688
+ # Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
654
689
  def destroy(*records)
655
- @association.destroy(*records)
690
+ @association.destroy(*records).tap { reset_scope }
656
691
  end
657
692
 
693
+ ##
694
+ # :method: distinct
695
+ #
696
+ # :call-seq:
697
+ # distinct(value = true)
698
+ #
658
699
  # Specifies whether the records should be unique or not.
659
700
  #
660
701
  # class Person < ActiveRecord::Base
@@ -669,17 +710,35 @@ module ActiveRecord
669
710
  #
670
711
  # person.pets.select(:name).distinct
671
712
  # # => [#<Pet name: "Fancy-Fancy">]
672
- def distinct
673
- @association.distinct
713
+ #
714
+ # person.pets.select(:name).distinct.distinct(false)
715
+ # # => [
716
+ # # #<Pet name: "Fancy-Fancy">,
717
+ # # #<Pet name: "Fancy-Fancy">
718
+ # # ]
719
+
720
+ #--
721
+ def calculate(operation, column_name)
722
+ null_scope? ? scope.calculate(operation, column_name) : super
674
723
  end
675
- alias uniq distinct
676
724
 
677
- # Count all records using SQL.
725
+ def pluck(*column_names)
726
+ null_scope? ? scope.pluck(*column_names) : super
727
+ end
728
+
729
+ ##
730
+ # :method: count
731
+ #
732
+ # :call-seq:
733
+ # count(column_name = nil, &block)
734
+ #
735
+ # Count all records.
678
736
  #
679
737
  # class Person < ActiveRecord::Base
680
738
  # has_many :pets
681
739
  # end
682
740
  #
741
+ # # This will perform the count using SQL.
683
742
  # person.pets.count # => 3
684
743
  # person.pets
685
744
  # # => [
@@ -687,11 +746,11 @@ module ActiveRecord
687
746
  # # #<Pet id: 2, name: "Spook", person_id: 1>,
688
747
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
689
748
  # # ]
690
- def count(column_name = nil, options = {})
691
- # TODO: Remove options argument as soon we remove support to
692
- # activerecord-deprecated_finders.
693
- @association.count(column_name, options)
694
- end
749
+ #
750
+ # Passing a block will select all of a person's pets in SQL and then
751
+ # perform the count using Ruby.
752
+ #
753
+ # person.pets.count { |pet| pet.name.include?('-') } # => 2
695
754
 
696
755
  # Returns the size of the collection. If the collection hasn't been loaded,
697
756
  # it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
@@ -721,6 +780,12 @@ module ActiveRecord
721
780
  @association.size
722
781
  end
723
782
 
783
+ ##
784
+ # :method: length
785
+ #
786
+ # :call-seq:
787
+ # length()
788
+ #
724
789
  # Returns the size of the collection calling +size+ on the target.
725
790
  # If the collection has been already loaded, +length+ and +size+ are
726
791
  # equivalent. If not and you are going to need the records anyway this
@@ -741,14 +806,11 @@ module ActiveRecord
741
806
  # # #<Pet id: 2, name: "Spook", person_id: 1>,
742
807
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
743
808
  # # ]
744
- def length
745
- @association.length
746
- end
747
809
 
748
810
  # Returns +true+ if the collection is empty. If the collection has been
749
811
  # loaded it is equivalent
750
812
  # to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
751
- # it is equivalent to <tt>collection.exists?</tt>. If the collection has
813
+ # it is equivalent to <tt>!collection.exists?</tt>. If the collection has
752
814
  # not already been loaded and you are going to fetch the records anyway it
753
815
  # is better to check <tt>collection.length.zero?</tt>.
754
816
  #
@@ -767,6 +829,12 @@ module ActiveRecord
767
829
  @association.empty?
768
830
  end
769
831
 
832
+ ##
833
+ # :method: any?
834
+ #
835
+ # :call-seq:
836
+ # any?()
837
+ #
770
838
  # Returns +true+ if the collection is not empty.
771
839
  #
772
840
  # class Person < ActiveRecord::Base
@@ -777,7 +845,7 @@ module ActiveRecord
777
845
  # person.pets.any? # => false
778
846
  #
779
847
  # person.pets << Pet.new(name: 'Snoop')
780
- # person.pets.count # => 0
848
+ # person.pets.count # => 1
781
849
  # person.pets.any? # => true
782
850
  #
783
851
  # You can also pass a +block+ to define criteria. The behavior
@@ -796,10 +864,13 @@ module ActiveRecord
796
864
  # pet.group == 'dogs'
797
865
  # end
798
866
  # # => true
799
- def any?(&block)
800
- @association.any?(&block)
801
- end
802
867
 
868
+ ##
869
+ # :method: many?
870
+ #
871
+ # :call-seq:
872
+ # many?()
873
+ #
803
874
  # Returns true if the collection has more than one record.
804
875
  # Equivalent to <tt>collection.size > 1</tt>.
805
876
  #
@@ -834,9 +905,6 @@ module ActiveRecord
834
905
  # pet.group == 'cats'
835
906
  # end
836
907
  # # => true
837
- def many?(&block)
838
- @association.many?(&block)
839
- end
840
908
 
841
909
  # Returns +true+ if the given +record+ is present in the collection.
842
910
  #
@@ -852,27 +920,14 @@ module ActiveRecord
852
920
  !!@association.include?(record)
853
921
  end
854
922
 
855
- def arel
856
- scope.arel
857
- end
858
-
859
923
  def proxy_association
860
924
  @association
861
925
  end
862
926
 
863
- # We don't want this object to be put on the scoping stack, because
864
- # that could create an infinite loop where we call an @association
865
- # method, which gets the current scope, which is this object, which
866
- # delegates to @association, and so on.
867
- def scoping
868
- @association.scope.scoping { yield }
869
- end
870
-
871
927
  # Returns a <tt>Relation</tt> object for the records in this association
872
928
  def scope
873
- @association.scope
929
+ @scope ||= @association.scope
874
930
  end
875
- alias spawn scope
876
931
 
877
932
  # Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
878
933
  # contain the same number of elements and if each element is equal
@@ -902,6 +957,12 @@ module ActiveRecord
902
957
  load_target == other
903
958
  end
904
959
 
960
+ ##
961
+ # :method: to_ary
962
+ #
963
+ # :call-seq:
964
+ # to_ary()
965
+ #
905
966
  # Returns a new array of objects from the collection. If the collection
906
967
  # hasn't been loaded, it fetches the records from the database.
907
968
  #
@@ -935,14 +996,15 @@ module ActiveRecord
935
996
  # # #<Pet id: 5, name: "Brain", person_id: 1>,
936
997
  # # #<Pet id: 6, name: "Boss", person_id: 1>
937
998
  # # ]
938
- def to_ary
939
- load_target.dup
999
+
1000
+ def records # :nodoc:
1001
+ load_target
940
1002
  end
941
- alias_method :to_a, :to_ary
942
1003
 
943
1004
  # Adds one or more +records+ to the collection by setting their foreign keys
944
- # to the association's primary key. Returns +self+, so several appends may be
945
- # chained together.
1005
+ # to the association's primary key. Since <tt><<</tt> flattens its argument list and
1006
+ # inserts each record, +push+ and +concat+ behave identically. Returns +self+
1007
+ # so several appends may be chained together.
946
1008
  #
947
1009
  # class Person < ActiveRecord::Base
948
1010
  # has_many :pets
@@ -965,21 +1027,24 @@ module ActiveRecord
965
1027
  end
966
1028
  alias_method :push, :<<
967
1029
  alias_method :append, :<<
1030
+ alias_method :concat, :<<
968
1031
 
969
- def prepend(*args)
970
- raise NoMethodError, "prepend on association is not defined. Please use << or append"
1032
+ def prepend(*args) # :nodoc:
1033
+ raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
971
1034
  end
972
1035
 
973
1036
  # Equivalent to +delete_all+. The difference is that returns +self+, instead
974
1037
  # of an array with the deleted objects, so methods can be chained. See
975
1038
  # +delete_all+ for more information.
1039
+ # Note that because +delete_all+ removes records by directly
1040
+ # running an SQL query into the database, the +updated_at+ column of
1041
+ # the object is not changed.
976
1042
  def clear
977
1043
  delete_all
978
1044
  self
979
1045
  end
980
1046
 
981
1047
  # Reloads the collection from the database. Returns +self+.
982
- # Equivalent to <tt>collection(true)</tt>.
983
1048
  #
984
1049
  # class Person < ActiveRecord::Base
985
1050
  # has_many :pets
@@ -993,12 +1058,9 @@ module ActiveRecord
993
1058
  #
994
1059
  # person.pets.reload # fetches pets from the database
995
1060
  # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
996
- #
997
- # person.pets(true) # fetches pets from the database
998
- # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
999
1061
  def reload
1000
- proxy_association.reload
1001
- self
1062
+ proxy_association.reload(true)
1063
+ reset_scope
1002
1064
  end
1003
1065
 
1004
1066
  # Unloads the association. Returns +self+.
@@ -1020,8 +1082,47 @@ module ActiveRecord
1020
1082
  def reset
1021
1083
  proxy_association.reset
1022
1084
  proxy_association.reset_scope
1085
+ reset_scope
1086
+ end
1087
+
1088
+ def reset_scope # :nodoc:
1089
+ @offsets = {}
1090
+ @scope = nil
1023
1091
  self
1024
1092
  end
1093
+
1094
+ delegate_methods = [
1095
+ QueryMethods,
1096
+ SpawnMethods,
1097
+ ].flat_map { |klass|
1098
+ klass.public_instance_methods(false)
1099
+ } - self.public_instance_methods(false) - [:select] + [:scoping, :values]
1100
+
1101
+ delegate(*delegate_methods, to: :scope)
1102
+
1103
+ private
1104
+
1105
+ def find_nth_with_limit(index, limit)
1106
+ load_target if find_from_target?
1107
+ super
1108
+ end
1109
+
1110
+ def find_nth_from_last(index)
1111
+ load_target if find_from_target?
1112
+ super
1113
+ end
1114
+
1115
+ def null_scope?
1116
+ @association.null_scope?
1117
+ end
1118
+
1119
+ def find_from_target?
1120
+ @association.find_from_target?
1121
+ end
1122
+
1123
+ def exec_queries
1124
+ load_target
1125
+ end
1025
1126
  end
1026
1127
  end
1027
1128
  end