ibm_db 5.1.0-x86-mingw32 → 5.3.2-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -1,79 +1,184 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/post'
3
- require 'models/tagging'
4
- require 'models/tag'
5
- require 'models/comment'
6
- require 'models/author'
7
- require 'models/essay'
8
- require 'models/category'
9
- require 'models/company'
10
- require 'models/person'
11
- require 'models/reader'
12
- require 'models/owner'
13
- require 'models/pet'
14
- require 'models/reference'
15
- require 'models/job'
16
- require 'models/subscriber'
17
- require 'models/subscription'
18
- require 'models/book'
19
- require 'models/developer'
20
- require 'models/computer'
21
- require 'models/project'
22
- require 'models/member'
23
- require 'models/membership'
24
- require 'models/club'
25
- require 'models/categorization'
26
- require 'models/sponsor'
27
- require 'models/mentor'
28
- require 'models/contract'
4
+ require "models/post"
5
+ require "models/tagging"
6
+ require "models/tag"
7
+ require "models/rating"
8
+ require "models/comment"
9
+ require "models/author"
10
+ require "models/essay"
11
+ require "models/category"
12
+ require "models/company"
13
+ require "models/person"
14
+ require "models/reader"
15
+ require "models/owner"
16
+ require "models/pet"
17
+ require "models/reference"
18
+ require "models/job"
19
+ require "models/subscriber"
20
+ require "models/subscription"
21
+ require "models/book"
22
+ require "models/citation"
23
+ require "models/developer"
24
+ require "models/computer"
25
+ require "models/project"
26
+ require "models/member"
27
+ require "models/membership"
28
+ require "models/club"
29
+ require "models/categorization"
30
+ require "models/sponsor"
31
+ require "models/mentor"
32
+ require "models/contract"
33
+
34
+ class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
35
+ fixtures :citations
36
+
37
+ def test_preloading_too_many_ids
38
+ assert_equal Citation.count, Citation.preload(:reference_of).to_a.size
39
+ end
40
+
41
+ def test_eager_loading_too_many_ids
42
+ assert_equal Citation.count, Citation.eager_load(:citations).offset(0).size
43
+ end
44
+ end
29
45
 
30
46
  class EagerAssociationTest < ActiveRecord::TestCase
31
47
  fixtures :posts, :comments, :authors, :essays, :author_addresses, :categories, :categories_posts,
32
- :companies, :accounts, :tags, :taggings, :people, :readers, :categorizations,
48
+ :companies, :accounts, :tags, :taggings, :ratings, :people, :readers, :categorizations,
33
49
  :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
34
50
  :developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors
35
51
 
36
52
  def test_eager_with_has_one_through_join_model_with_conditions_on_the_through
37
- member = Member.all.merge!(:includes => :favourite_club).find(members(:some_other_guy).id)
53
+ member = Member.all.merge!(includes: :favourite_club).find(members(:some_other_guy).id)
38
54
  assert_nil member.favourite_club
39
55
  end
40
56
 
57
+ def test_should_work_inverse_of_with_eager_load
58
+ author = authors(:david)
59
+ assert_same author, author.posts.first.author
60
+ assert_same author, author.posts.eager_load(:comments).first.author
61
+ end
62
+
41
63
  def test_loading_with_one_association
42
- posts = Post.all.merge!(:includes => :comments).to_a
64
+ posts = Post.all.merge!(includes: :comments).to_a
43
65
  post = posts.find { |p| p.id == 1 }
44
66
  assert_equal 2, post.comments.size
45
- assert post.comments.include?(comments(:greetings))
67
+ assert_includes post.comments, comments(:greetings)
46
68
 
47
- post = Post.all.merge!(:includes => :comments, :where => "posts.title = 'Welcome to the weblog'").first
69
+ post = Post.all.merge!(includes: :comments, where: "posts.title = 'Welcome to the weblog'").first
48
70
  assert_equal 2, post.comments.size
49
- assert post.comments.include?(comments(:greetings))
71
+ assert_includes post.comments, comments(:greetings)
50
72
 
51
- posts = Post.all.merge!(:includes => :last_comment).to_a
73
+ posts = Post.all.merge!(includes: :last_comment).to_a
52
74
  post = posts.find { |p| p.id == 1 }
53
75
  assert_equal Post.find(1).last_comment, post.last_comment
54
76
  end
55
77
 
56
78
  def test_loading_with_one_association_with_non_preload
57
- posts = Post.all.merge!(:includes => :last_comment, :order => 'comments.id DESC').to_a
79
+ posts = Post.all.merge!(includes: :last_comment, order: "comments.id DESC").to_a
58
80
  post = posts.find { |p| p.id == 1 }
59
81
  assert_equal Post.find(1).last_comment, post.last_comment
60
82
  end
61
83
 
62
84
  def test_loading_conditions_with_or
63
85
  posts = authors(:david).posts.references(:comments).merge(
64
- :includes => :comments,
65
- :where => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'"
86
+ includes: :comments,
87
+ where: "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'"
66
88
  ).to_a
67
89
  assert_nil posts.detect { |p| p.author_id != authors(:david).id },
68
90
  "expected to find only david's posts"
69
91
  end
70
92
 
93
+ def test_loading_polymorphic_association_with_mixed_table_conditions
94
+ rating = Rating.first
95
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_without_tag
96
+
97
+ rating = Rating.preload(:taggings_without_tag).first
98
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_without_tag
99
+
100
+ rating = Rating.eager_load(:taggings_without_tag).first
101
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_without_tag
102
+ end
103
+
104
+ def test_loading_association_with_string_joins
105
+ rating = Rating.first
106
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_with_no_tag
107
+
108
+ rating = Rating.preload(:taggings_with_no_tag).first
109
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_with_no_tag
110
+
111
+ rating = Rating.eager_load(:taggings_with_no_tag).first
112
+ assert_equal [taggings(:normal_comment_rating)], rating.taggings_with_no_tag
113
+ end
114
+
71
115
  def test_loading_with_scope_including_joins
72
- assert_equal clubs(:boring_club), Member.preload(:general_club).find(1).general_club
116
+ member = Member.first
117
+ assert_equal members(:groucho), member
118
+ assert_equal clubs(:boring_club), member.general_club
119
+
120
+ member = Member.preload(:general_club).first
121
+ assert_equal members(:groucho), member
122
+ assert_equal clubs(:boring_club), member.general_club
123
+
124
+ member = Member.eager_load(:general_club).first
125
+ assert_equal members(:groucho), member
126
+ assert_equal clubs(:boring_club), member.general_club
127
+ end
128
+
129
+ def test_loading_association_with_same_table_joins
130
+ super_memberships = [memberships(:super_membership_of_boring_club)]
131
+
132
+ member = Member.joins(:favourite_memberships).first
133
+ assert_equal members(:groucho), member
134
+ assert_equal super_memberships, member.super_memberships
135
+
136
+ member = Member.joins(:favourite_memberships).preload(:super_memberships).first
137
+ assert_equal members(:groucho), member
138
+ assert_equal super_memberships, member.super_memberships
139
+
140
+ member = Member.joins(:favourite_memberships).eager_load(:super_memberships).first
141
+ assert_equal members(:groucho), member
142
+ assert_equal super_memberships, member.super_memberships
143
+ end
144
+
145
+ def test_loading_association_with_intersection_joins
146
+ member = Member.joins(:current_membership).first
147
+ assert_equal members(:groucho), member
148
+ assert_equal clubs(:boring_club), member.club
149
+ assert_equal memberships(:membership_of_boring_club), member.current_membership
150
+
151
+ member = Member.joins(:current_membership).preload(:club, :current_membership).first
152
+ assert_equal members(:groucho), member
153
+ assert_equal clubs(:boring_club), member.club
154
+ assert_equal memberships(:membership_of_boring_club), member.current_membership
155
+
156
+ member = Member.joins(:current_membership).eager_load(:club, :current_membership).first
157
+ assert_equal members(:groucho), member
158
+ assert_equal clubs(:boring_club), member.club
159
+ assert_equal memberships(:membership_of_boring_club), member.current_membership
160
+ end
161
+
162
+ def test_loading_associations_dont_leak_instance_state
163
+ assertions = ->(firm) {
164
+ assert_equal companies(:first_firm), firm
165
+
166
+ assert_predicate firm.association(:readonly_account), :loaded?
167
+ assert_predicate firm.association(:accounts), :loaded?
168
+
169
+ assert_equal accounts(:signals37), firm.readonly_account
170
+ assert_equal [accounts(:signals37)], firm.accounts
171
+
172
+ assert_predicate firm.readonly_account, :readonly?
173
+ assert firm.accounts.none?(&:readonly?)
174
+ }
175
+
176
+ assertions.call(Firm.preload(:readonly_account, :accounts).first)
177
+ assertions.call(Firm.eager_load(:readonly_account, :accounts).first)
73
178
  end
74
179
 
75
180
  def test_with_ordering
76
- list = Post.all.merge!(:includes => :comments, :order => "posts.id DESC").to_a
181
+ list = Post.all.merge!(includes: :comments, order: "posts.id DESC").to_a
77
182
  [:other_by_mary, :other_by_bob, :misc_by_mary, :misc_by_bob, :eager_other,
78
183
  :sti_habtm, :sti_post_and_comments, :sti_comments, :authorless, :thinking, :welcome
79
184
  ].each_with_index do |post, index|
@@ -94,119 +199,84 @@ class EagerAssociationTest < ActiveRecord::TestCase
94
199
  assert_no_queries { authors.map(&:post) }
95
200
  end
96
201
 
97
- def test_with_two_tables_in_from_without_getting_double_quoted
98
- posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a
99
- assert_equal 2, posts.first.comments.size
100
- end
101
-
102
- def test_loading_with_multiple_associations
103
- posts = Post.all.merge!(:includes => [ :comments, :author, :categories ], :order => "posts.id").to_a
104
- assert_equal 2, posts.first.comments.size
105
- assert_equal 2, posts.first.categories.size
106
- assert posts.first.comments.include?(comments(:greetings))
107
- end
202
+ def test_type_cast_in_where_references_association_name
203
+ parent = comments(:greetings)
204
+ child = parent.children.create!(label: "child", body: "hi", post_id: parent.post_id)
108
205
 
109
- def test_duplicate_middle_objects
110
- comments = Comment.all.merge!(:where => 'post_id = 1', :includes => [:post => :author]).to_a
111
- assert_no_queries do
112
- comments.each {|comment| comment.post.author.name}
113
- end
114
- end
206
+ comment = Comment.includes(:children).where("children.label": "child").last
115
207
 
116
- def test_preloading_has_many_in_multiple_queries_with_more_ids_than_database_can_handle
117
- assert_called(Comment.connection, :in_clause_length, returns: 5) do
118
- posts = Post.all.merge!(:includes=>:comments).to_a
119
- assert_equal 11, posts.size
120
- end
208
+ assert_equal parent, comment
209
+ assert_equal [child], comment.children
121
210
  end
122
211
 
123
- def test_preloading_has_many_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
124
- assert_called(Comment.connection, :in_clause_length, returns: nil) do
125
- posts = Post.all.merge!(:includes=>:comments).to_a
126
- assert_equal 11, posts.size
127
- end
212
+ def test_attribute_alias_in_where_references_association_name
213
+ firm = Firm.includes(:clients).where("clients.new_name": "Summit").last
214
+ assert_equal companies(:first_firm), firm
215
+ assert_equal [companies(:first_client)], firm.clients
128
216
  end
129
217
 
130
- def test_preloading_habtm_in_multiple_queries_with_more_ids_than_database_can_handle
131
- assert_called(Comment.connection, :in_clause_length, times: 2, returns: 5) do
132
- posts = Post.all.merge!(:includes=>:categories).to_a
133
- assert_equal 11, posts.size
134
- end
218
+ def test_calculate_with_string_in_from_and_eager_loading
219
+ assert_equal 10, Post.from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").count
135
220
  end
136
221
 
137
- def test_preloading_habtm_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
138
- assert_called(Comment.connection, :in_clause_length, times: 2, returns: nil) do
139
- posts = Post.all.merge!(:includes=>:categories).to_a
140
- assert_equal 11, posts.size
141
- end
142
- end
143
-
144
- def test_load_associated_records_in_one_query_when_adapter_has_no_limit
145
- assert_called(Comment.connection, :in_clause_length, returns: nil) do
146
- post = posts(:welcome)
147
- assert_queries(2) do
148
- Post.includes(:comments).where(:id => post.id).to_a
149
- end
150
- end
222
+ def test_with_two_tables_in_from_without_getting_double_quoted
223
+ posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a
224
+ assert_equal 2, posts.first.comments.size
151
225
  end
152
226
 
153
- def test_load_associated_records_in_several_queries_when_many_ids_passed
154
- assert_called(Comment.connection, :in_clause_length, returns: 1) do
155
- post1, post2 = posts(:welcome), posts(:thinking)
156
- assert_queries(3) do
157
- Post.includes(:comments).where(:id => [post1.id, post2.id]).to_a
158
- end
159
- end
227
+ def test_loading_with_multiple_associations
228
+ posts = Post.all.merge!(includes: [ :comments, :author, :categories ], order: "posts.id").to_a
229
+ assert_equal 2, posts.first.comments.size
230
+ assert_equal 2, posts.first.categories.size
231
+ assert_includes posts.first.comments, comments(:greetings)
160
232
  end
161
233
 
162
- def test_load_associated_records_in_one_query_when_a_few_ids_passed
163
- assert_called(Comment.connection, :in_clause_length, returns: 3) do
164
- post = posts(:welcome)
165
- assert_queries(2) do
166
- Post.includes(:comments).where(:id => post.id).to_a
167
- end
234
+ def test_duplicate_middle_objects
235
+ comments = Comment.all.merge!(where: "post_id = 1", includes: [post: :author]).to_a
236
+ assert_no_queries do
237
+ comments.each { |comment| comment.post.author.name }
168
238
  end
169
239
  end
170
240
 
171
241
  def test_including_duplicate_objects_from_belongs_to
172
- popular_post = Post.create!(:title => 'foo', :body => "I like cars!")
173
- comment = popular_post.comments.create!(:body => "lol")
174
- popular_post.readers.create!(:person => people(:michael))
175
- popular_post.readers.create!(:person => people(:david))
242
+ popular_post = Post.create!(title: "foo", body: "I like cars!")
243
+ comment = popular_post.comments.create!(body: "lol")
244
+ popular_post.readers.create!(person: people(:michael))
245
+ popular_post.readers.create!(person: people(:david))
176
246
 
177
- readers = Reader.all.merge!(:where => ["post_id = ?", popular_post.id],
178
- :includes => {:post => :comments}).to_a
247
+ readers = Reader.all.merge!(where: ["post_id = ?", popular_post.id],
248
+ includes: { post: :comments }).to_a
179
249
  readers.each do |reader|
180
250
  assert_equal [comment], reader.post.comments
181
251
  end
182
252
  end
183
253
 
184
254
  def test_including_duplicate_objects_from_has_many
185
- car_post = Post.create!(:title => 'foo', :body => "I like cars!")
255
+ car_post = Post.create!(title: "foo", body: "I like cars!")
186
256
  car_post.categories << categories(:general)
187
257
  car_post.categories << categories(:technology)
188
258
 
189
- comment = car_post.comments.create!(:body => "hmm")
190
- categories = Category.all.merge!(:where => { 'posts.id' => car_post.id },
191
- :includes => {:posts => :comments}).to_a
259
+ comment = car_post.comments.create!(body: "hmm")
260
+ categories = Category.all.merge!(where: { "posts.id" => car_post.id },
261
+ includes: { posts: :comments }).to_a
192
262
  categories.each do |category|
193
263
  assert_equal [comment], category.posts[0].comments
194
264
  end
195
265
  end
196
266
 
197
267
  def test_associations_loaded_for_all_records
198
- post = Post.create!(:title => 'foo', :body => "I like cars!")
199
- SpecialComment.create!(:body => 'Come on!', :post => post)
200
- first_category = Category.create! :name => 'First!', :posts => [post]
201
- second_category = Category.create! :name => 'Second!', :posts => [post]
268
+ post = Post.create!(title: "foo", body: "I like cars!")
269
+ SpecialComment.create!(body: "Come on!", post: post)
270
+ first_category = Category.create! name: "First!", posts: [post]
271
+ second_category = Category.create! name: "Second!", posts: [post]
202
272
 
203
- categories = Category.where(:id => [first_category.id, second_category.id]).includes(:posts => :special_comments)
273
+ categories = Category.where(id: [first_category.id, second_category.id]).includes(posts: :special_comments)
204
274
  assert_equal categories.map { |category| category.posts.first.special_comments.loaded? }, [true, true]
205
275
  end
206
276
 
207
277
  def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once
208
278
  author_id = authors(:david).id
209
- author = assert_queries(3) { Author.all.merge!(:includes => {:posts_with_comments => :comments}).find(author_id) } # find the author, then find the posts, then find the comments
279
+ author = assert_queries(3) { Author.all.merge!(includes: { posts_with_comments: :comments }).find(author_id) } # find the author, then find the posts, then find the comments
210
280
  author.posts_with_comments.each do |post_with_comments|
211
281
  assert_equal post_with_comments.comments.length, post_with_comments.comments.count
212
282
  assert_nil post_with_comments.comments.to_a.uniq!
@@ -217,7 +287,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
217
287
  author = authors(:david)
218
288
  post = author.post_about_thinking_with_last_comment
219
289
  last_comment = post.last_comment
220
- author = assert_queries(3) { Author.all.merge!(:includes => {:post_about_thinking_with_last_comment => :last_comment}).find(author.id)} # find the author, then find the posts, then find the comments
290
+ author = assert_queries(3) { Author.all.merge!(includes: { post_about_thinking_with_last_comment: :last_comment }).find(author.id) } # find the author, then find the posts, then find the comments
221
291
  assert_no_queries do
222
292
  assert_equal post, author.post_about_thinking_with_last_comment
223
293
  assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment
@@ -228,7 +298,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
228
298
  post = posts(:welcome)
229
299
  author = post.author
230
300
  author_address = author.author_address
231
- post = assert_queries(3) { Post.all.merge!(:includes => {:author_with_address => :author_address}).find(post.id) } # find the post, then find the author, then find the address
301
+ post = assert_queries(3) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) } # find the post, then find the author, then find the address
232
302
  assert_no_queries do
233
303
  assert_equal author, post.author_with_address
234
304
  assert_equal author_address, post.author_with_address.author_address
@@ -238,53 +308,50 @@ class EagerAssociationTest < ActiveRecord::TestCase
238
308
  def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
239
309
  post = posts(:welcome)
240
310
  post.update!(author: nil)
241
- post = assert_queries(1) { Post.all.merge!(includes: {author_with_address: :author_address}).find(post.id) }
311
+ post = assert_queries(1) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) }
242
312
  # find the post, then find the author which is null so no query for the author or address
243
313
  assert_no_queries do
244
- assert_equal nil, post.author_with_address
314
+ assert_nil post.author_with_address
245
315
  end
246
316
  end
247
317
 
248
318
  def test_finding_with_includes_on_null_belongs_to_polymorphic_association
249
319
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
250
320
  sponsor.update!(sponsorable: nil)
251
- sponsor = assert_queries(1) { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) }
321
+ sponsor = assert_queries(1) { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) }
252
322
  assert_no_queries do
253
- assert_equal nil, sponsor.sponsorable
323
+ assert_nil sponsor.sponsorable
254
324
  end
255
325
  end
256
326
 
257
327
  def test_finding_with_includes_on_empty_polymorphic_type_column
258
328
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
259
- sponsor.update!(sponsorable_type: '', sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL
329
+ sponsor.update!(sponsorable_type: "", sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL
260
330
  sponsor = assert_queries(1) do
261
- assert_nothing_raised { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) }
331
+ assert_nothing_raised { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) }
262
332
  end
263
333
  assert_no_queries do
264
- assert_equal nil, sponsor.sponsorable
334
+ assert_nil sponsor.sponsorable
265
335
  end
266
336
  end
267
337
 
268
338
  def test_loading_from_an_association
269
- posts = authors(:david).posts.merge(:includes => :comments, :order => "posts.id").to_a
339
+ posts = authors(:david).posts.merge(includes: :comments, order: "posts.id").to_a
270
340
  assert_equal 2, posts.first.comments.size
271
341
  end
272
342
 
273
343
  def test_loading_from_an_association_that_has_a_hash_of_conditions
274
- assert_nothing_raised do
275
- Author.all.merge!(:includes => :hello_posts_with_hash_conditions).to_a
276
- end
277
- assert !Author.all.merge!(:includes => :hello_posts_with_hash_conditions).find(authors(:david).id).hello_posts.empty?
344
+ assert_not_empty Author.all.merge!(includes: :hello_posts_with_hash_conditions).find(authors(:david).id).hello_posts
278
345
  end
279
346
 
280
347
  def test_loading_with_no_associations
281
- assert_nil Post.all.merge!(:includes => :author).find(posts(:authorless).id).author
348
+ assert_nil Post.all.merge!(includes: :author).find(posts(:authorless).id).author
282
349
  end
283
350
 
284
351
  # Regression test for 21c75e5
285
352
  def test_nested_loading_does_not_raise_exception_when_association_does_not_exist
286
353
  assert_nothing_raised do
287
- Post.all.merge!(:includes => {:author => :author_addresss}).find(posts(:authorless).id)
354
+ Post.all.merge!(includes: { author: :author_addresss }).find(posts(:authorless).id)
288
355
  end
289
356
  end
290
357
 
@@ -292,117 +359,117 @@ class EagerAssociationTest < ActiveRecord::TestCase
292
359
  post_id = Comment.where(author_id: nil).where.not(post_id: nil).first.post_id
293
360
 
294
361
  assert_nothing_raised do
295
- Post.preload(:comments => [{:author => :essays}]).find(post_id)
362
+ Post.preload(comments: [{ author: :essays }]).find(post_id)
296
363
  end
297
364
  end
298
365
 
299
366
  def test_nested_loading_through_has_one_association
300
- aa = AuthorAddress.all.merge!(:includes => {:author => :posts}).find(author_addresses(:david_address).id)
367
+ aa = AuthorAddress.all.merge!(includes: { author: :posts }).find(author_addresses(:david_address).id)
301
368
  assert_equal aa.author.posts.count, aa.author.posts.length
302
369
  end
303
370
 
304
371
  def test_nested_loading_through_has_one_association_with_order
305
- aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'author_addresses.id').find(author_addresses(:david_address).id)
372
+ aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "author_addresses.id").find(author_addresses(:david_address).id)
306
373
  assert_equal aa.author.posts.count, aa.author.posts.length
307
374
  end
308
375
 
309
376
  def test_nested_loading_through_has_one_association_with_order_on_association
310
- aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'authors.id').find(author_addresses(:david_address).id)
377
+ aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "authors.id").find(author_addresses(:david_address).id)
311
378
  assert_equal aa.author.posts.count, aa.author.posts.length
312
379
  end
313
380
 
314
381
  def test_nested_loading_through_has_one_association_with_order_on_nested_association
315
- aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'posts.id').find(author_addresses(:david_address).id)
382
+ aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "posts.id").find(author_addresses(:david_address).id)
316
383
  assert_equal aa.author.posts.count, aa.author.posts.length
317
384
  end
318
385
 
319
386
  def test_nested_loading_through_has_one_association_with_conditions
320
387
  aa = AuthorAddress.references(:author_addresses).merge(
321
- :includes => {:author => :posts},
322
- :where => "author_addresses.id > 0"
388
+ includes: { author: :posts },
389
+ where: "author_addresses.id > 0"
323
390
  ).find author_addresses(:david_address).id
324
391
  assert_equal aa.author.posts.count, aa.author.posts.length
325
392
  end
326
393
 
327
394
  def test_nested_loading_through_has_one_association_with_conditions_on_association
328
395
  aa = AuthorAddress.references(:authors).merge(
329
- :includes => {:author => :posts},
330
- :where => "authors.id > 0"
396
+ includes: { author: :posts },
397
+ where: "authors.id > 0"
331
398
  ).find author_addresses(:david_address).id
332
399
  assert_equal aa.author.posts.count, aa.author.posts.length
333
400
  end
334
401
 
335
402
  def test_nested_loading_through_has_one_association_with_conditions_on_nested_association
336
403
  aa = AuthorAddress.references(:posts).merge(
337
- :includes => {:author => :posts},
338
- :where => "posts.id > 0"
404
+ includes: { author: :posts },
405
+ where: "posts.id > 0"
339
406
  ).find author_addresses(:david_address).id
340
407
  assert_equal aa.author.posts.count, aa.author.posts.length
341
408
  end
342
409
 
343
410
  def test_eager_association_loading_with_belongs_to_and_foreign_keys
344
- pets = Pet.all.merge!(:includes => :owner).to_a
411
+ pets = Pet.all.merge!(includes: :owner).to_a
345
412
  assert_equal 4, pets.length
346
413
  end
347
414
 
348
415
  def test_eager_association_loading_with_belongs_to
349
- comments = Comment.all.merge!(:includes => :post).to_a
350
- assert_equal 11, comments.length
416
+ comments = Comment.all.merge!(includes: :post).to_a
417
+ assert_equal 12, comments.length
351
418
  titles = comments.map { |c| c.post.title }
352
- assert titles.include?(posts(:welcome).title)
353
- assert titles.include?(posts(:sti_post_and_comments).title)
419
+ assert_includes titles, posts(:welcome).title
420
+ assert_includes titles, posts(:sti_post_and_comments).title
354
421
  end
355
422
 
356
423
  def test_eager_association_loading_with_belongs_to_and_limit
357
- comments = Comment.all.merge!(:includes => :post, :limit => 5, :order => 'comments.id').to_a
424
+ comments = Comment.all.merge!(includes: :post, limit: 5, order: "comments.id").to_a
358
425
  assert_equal 5, comments.length
359
- assert_equal [1,2,3,5,6], comments.collect(&:id)
426
+ assert_equal [1, 2, 3, 5, 6], comments.collect(&:id)
360
427
  end
361
428
 
362
429
  def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
363
- comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :order => 'comments.id').to_a
430
+ comments = Comment.all.merge!(includes: :post, where: "post_id = 4", limit: 3, order: "comments.id").to_a
364
431
  assert_equal 3, comments.length
365
- assert_equal [5,6,7], comments.collect(&:id)
432
+ assert_equal [5, 6, 7], comments.collect(&:id)
366
433
  end
367
434
 
368
435
  def test_eager_association_loading_with_belongs_to_and_limit_and_offset
369
- comments = Comment.all.merge!(:includes => :post, :limit => 3, :offset => 2, :order => 'comments.id').to_a
436
+ comments = Comment.all.merge!(includes: :post, limit: 3, offset: 2, order: "comments.id").to_a
370
437
  assert_equal 3, comments.length
371
- assert_equal [3,5,6], comments.collect(&:id)
438
+ assert_equal [3, 5, 6], comments.collect(&:id)
372
439
  end
373
440
 
374
441
  def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
375
- comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id').to_a
442
+ comments = Comment.all.merge!(includes: :post, where: "post_id = 4", limit: 3, offset: 1, order: "comments.id").to_a
376
443
  assert_equal 3, comments.length
377
- assert_equal [6,7,8], comments.collect(&:id)
444
+ assert_equal [6, 7, 8], comments.collect(&:id)
378
445
  end
379
446
 
380
447
  def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
381
- comments = Comment.all.merge!(:includes => :post, :where => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id').to_a
448
+ comments = Comment.all.merge!(includes: :post, where: ["post_id = ?", 4], limit: 3, offset: 1, order: "comments.id").to_a
382
449
  assert_equal 3, comments.length
383
- assert_equal [6,7,8], comments.collect(&:id)
450
+ assert_equal [6, 7, 8], comments.collect(&:id)
384
451
  end
385
452
 
386
453
  def test_eager_association_loading_with_belongs_to_and_conditions_string_with_unquoted_table_name
387
454
  assert_nothing_raised do
388
- Comment.includes(:post).references(:posts).where('posts.id = ?', 4)
455
+ Comment.includes(:post).references(:posts).where("posts.id = ?", 4)
389
456
  end
390
457
  end
391
458
 
392
459
  def test_eager_association_loading_with_belongs_to_and_conditions_hash
393
460
  comments = []
394
461
  assert_nothing_raised do
395
- comments = Comment.all.merge!(:includes => :post, :where => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id').to_a
462
+ comments = Comment.all.merge!(includes: :post, where: { posts: { id: 4 } }, limit: 3, order: "comments.id").to_a
396
463
  end
397
464
  assert_equal 3, comments.length
398
- assert_equal [5,6,7], comments.collect(&:id)
465
+ assert_equal [5, 6, 7], comments.collect(&:id)
399
466
  assert_no_queries do
400
467
  comments.first.post
401
468
  end
402
469
  end
403
470
 
404
471
  def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name
405
- quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
472
+ quoted_posts_id = Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id")
406
473
  assert_nothing_raised do
407
474
  Comment.includes(:post).references(:posts).where("#{quoted_posts_id} = ?", 4)
408
475
  end
@@ -410,61 +477,61 @@ class EagerAssociationTest < ActiveRecord::TestCase
410
477
 
411
478
  def test_eager_association_loading_with_belongs_to_and_order_string_with_unquoted_table_name
412
479
  assert_nothing_raised do
413
- Comment.all.merge!(:includes => :post, :order => 'posts.id').to_a
480
+ Comment.all.merge!(includes: :post, order: "posts.id").to_a
414
481
  end
415
482
  end
416
483
 
417
484
  def test_eager_association_loading_with_belongs_to_and_order_string_with_quoted_table_name
418
- quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id')
485
+ quoted_posts_id = Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id")
419
486
  assert_nothing_raised do
420
487
  Comment.includes(:post).references(:posts).order(quoted_posts_id)
421
488
  end
422
489
  end
423
490
 
424
491
  def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
425
- posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :order => 'posts.id').to_a
492
+ posts = Post.all.merge!(includes: [:author, :very_special_comment], limit: 1, order: "posts.id").to_a
426
493
  assert_equal 1, posts.length
427
494
  assert_equal [1], posts.collect(&:id)
428
495
  end
429
496
 
430
497
  def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
431
- posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id').to_a
498
+ posts = Post.all.merge!(includes: [:author, :very_special_comment], limit: 1, offset: 1, order: "posts.id").to_a
432
499
  assert_equal 1, posts.length
433
500
  assert_equal [2], posts.collect(&:id)
434
501
  end
435
502
 
436
503
  def test_eager_association_loading_with_belongs_to_inferred_foreign_key_from_association_name
437
- author_favorite = AuthorFavorite.all.merge!(:includes => :favorite_author).first
504
+ author_favorite = AuthorFavorite.all.merge!(includes: :favorite_author).first
438
505
  assert_equal authors(:mary), assert_no_queries { author_favorite.favorite_author }
439
506
  end
440
507
 
441
508
  def test_eager_load_belongs_to_quotes_table_and_column_names
442
509
  job = Job.includes(:ideal_reference).find jobs(:unicyclist).id
443
510
  references(:michael_unicyclist)
444
- assert_no_queries{ assert_equal references(:michael_unicyclist), job.ideal_reference}
511
+ assert_no_queries { assert_equal references(:michael_unicyclist), job.ideal_reference }
445
512
  end
446
513
 
447
514
  def test_eager_load_has_one_quotes_table_and_column_names
448
- michael = Person.all.merge!(:includes => :favourite_reference).find(people(:michael).id)
515
+ michael = Person.all.merge!(includes: :favourite_reference).find(people(:michael).id)
449
516
  references(:michael_unicyclist)
450
- assert_no_queries{ assert_equal references(:michael_unicyclist), michael.favourite_reference}
517
+ assert_no_queries { assert_equal references(:michael_unicyclist), michael.favourite_reference }
451
518
  end
452
519
 
453
520
  def test_eager_load_has_many_quotes_table_and_column_names
454
- michael = Person.all.merge!(:includes => :references).find(people(:michael).id)
455
- references(:michael_magician,:michael_unicyclist)
456
- assert_no_queries{ assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) }
521
+ michael = Person.all.merge!(includes: :references).find(people(:michael).id)
522
+ references(:michael_magician, :michael_unicyclist)
523
+ assert_no_queries { assert_equal references(:michael_magician, :michael_unicyclist), michael.references.sort_by(&:id) }
457
524
  end
458
525
 
459
526
  def test_eager_load_has_many_through_quotes_table_and_column_names
460
- michael = Person.all.merge!(:includes => :jobs).find(people(:michael).id)
527
+ michael = Person.all.merge!(includes: :jobs).find(people(:michael).id)
461
528
  jobs(:magician, :unicyclist)
462
- assert_no_queries{ assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) }
529
+ assert_no_queries { assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) }
463
530
  end
464
531
 
465
532
  def test_eager_load_has_many_with_string_keys
466
533
  subscriptions = subscriptions(:webster_awdr, :webster_rfr)
467
- subscriber =Subscriber.all.merge!(:includes => :subscriptions).find(subscribers(:second).id)
534
+ subscriber = Subscriber.all.merge!(includes: :subscriptions).find(subscribers(:second).id)
468
535
  assert_equal subscriptions, subscriber.subscriptions.sort_by(&:id)
469
536
  end
470
537
 
@@ -475,32 +542,32 @@ class EagerAssociationTest < ActiveRecord::TestCase
475
542
 
476
543
  b = Book.create!
477
544
 
478
- Subscription.create!(:subscriber_id => "PL", :book_id => b.id)
545
+ Subscription.create!(subscriber_id: "PL", book_id: b.id)
479
546
  s.reload
480
547
  s.book_ids = s.book_ids
481
548
  end
482
549
 
483
550
  def test_eager_load_has_many_through_with_string_keys
484
551
  books = books(:awdr, :rfr)
485
- subscriber = Subscriber.all.merge!(:includes => :books).find(subscribers(:second).id)
552
+ subscriber = Subscriber.all.merge!(includes: :books).find(subscribers(:second).id)
486
553
  assert_equal books, subscriber.books.sort_by(&:id)
487
554
  end
488
555
 
489
556
  def test_eager_load_belongs_to_with_string_keys
490
557
  subscriber = subscribers(:second)
491
- subscription = Subscription.all.merge!(:includes => :subscriber).find(subscriptions(:webster_awdr).id)
558
+ subscription = Subscription.all.merge!(includes: :subscriber).find(subscriptions(:webster_awdr).id)
492
559
  assert_equal subscriber, subscription.subscriber
493
560
  end
494
561
 
495
562
  def test_eager_association_loading_with_explicit_join
496
- posts = Post.all.merge!(:includes => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id').to_a
563
+ posts = Post.all.merge!(includes: :comments, joins: "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", limit: 1, order: "author_id").to_a
497
564
  assert_equal 1, posts.length
498
565
  end
499
566
 
500
567
  def test_eager_with_has_many_through
501
- posts_with_comments = people(:michael).posts.merge(:includes => :comments, :order => 'posts.id').to_a
502
- posts_with_author = people(:michael).posts.merge(:includes => :author, :order => 'posts.id').to_a
503
- posts_with_comments_and_author = people(:michael).posts.merge(:includes => [ :comments, :author ], :order => 'posts.id').to_a
568
+ posts_with_comments = people(:michael).posts.merge(includes: :comments, order: "posts.id").to_a
569
+ posts_with_author = people(:michael).posts.merge(includes: :author, order: "posts.id").to_a
570
+ posts_with_comments_and_author = people(:michael).posts.merge(includes: [ :comments, :author ], order: "posts.id").to_a
504
571
  assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum + post.comments.size }
505
572
  assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
506
573
  assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
@@ -508,35 +575,58 @@ class EagerAssociationTest < ActiveRecord::TestCase
508
575
 
509
576
  def test_eager_with_has_many_through_a_belongs_to_association
510
577
  author = authors(:mary)
511
- Post.create!(:author => author, :title => "TITLE", :body => "BODY")
512
- author.author_favorites.create(:favorite_author_id => 1)
513
- author.author_favorites.create(:favorite_author_id => 2)
514
- posts_with_author_favorites = author.posts.merge(:includes => :author_favorites).to_a
578
+ Post.create!(author: author, title: "TITLE", body: "BODY")
579
+ author.author_favorites.create(favorite_author_id: 1)
580
+ author.author_favorites.create(favorite_author_id: 2)
581
+ posts_with_author_favorites = author.posts.merge(includes: :author_favorites).to_a
515
582
  assert_no_queries { posts_with_author_favorites.first.author_favorites.first.author_id }
516
583
  end
517
584
 
518
585
  def test_eager_with_has_many_through_an_sti_join_model
519
- author = Author.all.merge!(:includes => :special_post_comments, :order => 'authors.id').first
586
+ author = Author.all.merge!(includes: :special_post_comments, order: "authors.id").first
520
587
  assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
521
588
  end
522
589
 
590
+ def test_preloading_with_has_one_through_an_sti_with_after_initialize
591
+ author_a = Author.create!(name: "A")
592
+ author_b = Author.create!(name: "B")
593
+ post_a = StiPost.create!(author: author_a, title: "TITLE", body: "BODY")
594
+ post_b = SpecialPost.create!(author: author_b, title: "TITLE", body: "BODY")
595
+ comment_a = SpecialComment.create!(post: post_a, body: "TEST")
596
+ comment_b = SpecialComment.create!(post: post_b, body: "TEST")
597
+ reset_callbacks(StiPost, :initialize) do
598
+ StiPost.after_initialize { author }
599
+ SpecialComment.where(id: [comment_a.id, comment_b.id]).includes(:author).each do |comment|
600
+ assert comment.author
601
+ end
602
+ end
603
+ end
604
+
605
+ def test_preloading_has_many_through_with_implicit_source
606
+ authors = Author.includes(:very_special_comments).to_a.sort_by(&:id)
607
+ assert_no_queries do
608
+ special_comment_authors = authors.map { |author| [author.name, author.very_special_comments.size] }
609
+ assert_equal [["David", 1], ["Mary", 0], ["Bob", 0]], special_comment_authors
610
+ end
611
+ end
612
+
523
613
  def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
524
- author = Author.all.merge!(:includes => :special_nonexistent_post_comments, :order => 'authors.id').first
614
+ author = Author.all.merge!(includes: :special_nonexistent_post_comments, order: "authors.id").first
525
615
  assert_equal [], author.special_nonexistent_post_comments
526
616
  end
527
617
 
528
618
  def test_eager_with_has_many_through_join_model_with_conditions
529
- assert_equal Author.all.merge!(:includes => :hello_post_comments,
530
- :order => 'authors.id').first.hello_post_comments.sort_by(&:id),
531
- Author.all.merge!(:order => 'authors.id').first.hello_post_comments.sort_by(&:id)
619
+ assert_equal Author.all.merge!(includes: :hello_post_comments,
620
+ order: "authors.id").first.hello_post_comments.sort_by(&:id),
621
+ Author.all.merge!(order: "authors.id").first.hello_post_comments.sort_by(&:id)
532
622
  end
533
623
 
534
624
  def test_eager_with_has_many_through_join_model_with_conditions_on_top_level
535
- assert_equal comments(:more_greetings), Author.all.merge!(:includes => :comments_with_order_and_conditions).find(authors(:david).id).comments_with_order_and_conditions.first
625
+ assert_equal comments(:more_greetings), Author.all.merge!(includes: :comments_with_order_and_conditions).find(authors(:david).id).comments_with_order_and_conditions.first
536
626
  end
537
627
 
538
628
  def test_eager_with_has_many_through_join_model_with_include
539
- author_comments = Author.all.merge!(:includes => :comments_with_include).find(authors(:david).id).comments_with_include.to_a
629
+ author_comments = Author.all.merge!(includes: :comments_with_include).find(authors(:david).id).comments_with_include.to_a
540
630
  assert_no_queries do
541
631
  author_comments.first.post.title
542
632
  end
@@ -544,7 +634,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
544
634
 
545
635
  def test_eager_with_has_many_through_with_conditions_join_model_with_include
546
636
  post_tags = Post.find(posts(:welcome).id).misc_tags
547
- eager_post_tags = Post.all.merge!(:includes => :misc_tags).find(1).misc_tags
637
+ eager_post_tags = Post.all.merge!(includes: :misc_tags).find(1).misc_tags
548
638
  assert_equal post_tags, eager_post_tags
549
639
  end
550
640
 
@@ -555,67 +645,67 @@ class EagerAssociationTest < ActiveRecord::TestCase
555
645
  end
556
646
 
557
647
  def test_eager_with_has_many_and_limit
558
- posts = Post.all.merge!(:order => 'posts.id asc', :includes => [ :author, :comments ], :limit => 2).to_a
648
+ posts = Post.all.merge!(order: "posts.id asc", includes: [ :author, :comments ], limit: 2).to_a
559
649
  assert_equal 2, posts.size
560
650
  assert_equal 3, posts.inject(0) { |sum, post| sum + post.comments.size }
561
651
  end
562
652
 
563
653
  def test_eager_with_has_many_and_limit_and_conditions
564
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.body = 'hello'", :order => "posts.id").to_a
654
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: "posts.body = 'hello'", order: "posts.id").to_a
565
655
  assert_equal 2, posts.size
566
- assert_equal [4,5], posts.collect(&:id)
656
+ assert_equal [4, 5], posts.collect(&:id)
567
657
  end
568
658
 
569
659
  def test_eager_with_has_many_and_limit_and_conditions_array
570
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => [ "posts.body = ?", 'hello' ], :order => "posts.id").to_a
660
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: [ "posts.body = ?", "hello" ], order: "posts.id").to_a
571
661
  assert_equal 2, posts.size
572
- assert_equal [4,5], posts.collect(&:id)
662
+ assert_equal [4, 5], posts.collect(&:id)
573
663
  end
574
664
 
575
665
  def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
576
- posts = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David')
666
+ posts = Post.includes(:author, :comments).limit(2).references("author").where("authors.name = ?", "David")
577
667
  assert_equal 2, posts.size
578
668
 
579
- count = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David').count
669
+ count = Post.includes(:author, :comments).limit(2).references("author").where("authors.name = ?", "David").count
580
670
  assert_equal posts.size, count
581
671
  end
582
672
 
583
673
  def test_eager_with_has_many_and_limit_and_high_offset
584
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).to_a
674
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10, where: { "authors.name" => "David" }).to_a
585
675
  assert_equal 0, posts.size
586
676
  end
587
677
 
588
678
  def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
589
679
  assert_queries(1) do
590
680
  posts = Post.references(:authors, :comments).
591
- merge(:includes => [ :author, :comments ], :limit => 2, :offset => 10,
592
- :where => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ]).to_a
681
+ merge(includes: [ :author, :comments ], limit: 2, offset: 10,
682
+ where: [ "authors.name = ? and comments.body = ?", "David", "go crazy" ]).to_a
593
683
  assert_equal 0, posts.size
594
684
  end
595
685
  end
596
686
 
597
687
  def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
598
688
  assert_queries(1) do
599
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10,
600
- :where => { 'authors.name' => 'David', 'comments.body' => 'go crazy' }).to_a
689
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10,
690
+ where: { "authors.name" => "David", "comments.body" => "go crazy" }).to_a
601
691
  assert_equal 0, posts.size
602
692
  end
603
693
  end
604
694
 
605
695
  def test_count_eager_with_has_many_and_limit_and_high_offset
606
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).count(:all)
696
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10, where: { "authors.name" => "David" }).count(:all)
607
697
  assert_equal 0, posts
608
698
  end
609
699
 
610
700
  def test_eager_with_has_many_and_limit_with_no_results
611
- posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.title = 'magic forest'").to_a
701
+ posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: "posts.title = 'magic forest'").to_a
612
702
  assert_equal 0, posts.size
613
703
  end
614
704
 
615
705
  def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional
616
706
  author = authors(:david)
617
707
  author_posts_without_comments = author.posts.select { |post| post.comments.blank? }
618
- assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where('comments.id is null').references(:comments).count
708
+ assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where("comments.id is null").references(:comments).count
619
709
  end
620
710
 
621
711
  def test_eager_count_performed_on_a_has_many_through_association_with_multi_table_conditional
@@ -625,13 +715,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
625
715
  end
626
716
 
627
717
  def test_eager_with_has_and_belongs_to_many_and_limit
628
- posts = Post.all.merge!(:includes => :categories, :order => "posts.id", :limit => 3).to_a
718
+ posts = Post.all.merge!(includes: :categories, order: "posts.id", limit: 3).to_a
629
719
  assert_equal 3, posts.size
630
720
  assert_equal 2, posts[0].categories.size
631
721
  assert_equal 1, posts[1].categories.size
632
722
  assert_equal 0, posts[2].categories.size
633
- assert posts[0].categories.include?(categories(:technology))
634
- assert posts[1].categories.include?(categories(:general))
723
+ assert_includes posts[0].categories, categories(:technology)
724
+ assert_includes posts[1].categories, categories(:general)
635
725
  end
636
726
 
637
727
  # Since the preloader for habtm gets raw row hashes from the database and then
@@ -647,7 +737,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
647
737
  post1 = general.posts.to_a.find { |p| p == welcome }
648
738
  post2 = technology.posts.to_a.find { |p| p == welcome }
649
739
 
650
- assert_equal post1.object_id, post2.object_id
740
+ assert_same post1, post2
651
741
  end
652
742
 
653
743
  def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
@@ -675,7 +765,6 @@ class EagerAssociationTest < ActiveRecord::TestCase
675
765
  .where("comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'")
676
766
  .references(:comments)
677
767
  .scoping do
678
-
679
768
  posts = authors(:david).posts.limit(2).to_a
680
769
  assert_equal 2, posts.size
681
770
  end
@@ -684,39 +773,38 @@ class EagerAssociationTest < ActiveRecord::TestCase
684
773
  .where("authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')")
685
774
  .references(:authors, :comments)
686
775
  .scoping do
687
-
688
776
  count = Post.limit(2).count
689
777
  assert_equal count, posts.size
690
778
  end
691
779
  end
692
780
 
693
781
  def test_eager_association_loading_with_habtm
694
- posts = Post.all.merge!(:includes => :categories, :order => "posts.id").to_a
782
+ posts = Post.all.merge!(includes: :categories, order: "posts.id").to_a
695
783
  assert_equal 2, posts[0].categories.size
696
784
  assert_equal 1, posts[1].categories.size
697
785
  assert_equal 0, posts[2].categories.size
698
- assert posts[0].categories.include?(categories(:technology))
699
- assert posts[1].categories.include?(categories(:general))
786
+ assert_includes posts[0].categories, categories(:technology)
787
+ assert_includes posts[1].categories, categories(:general)
700
788
  end
701
789
 
702
790
  def test_eager_with_inheritance
703
- SpecialPost.all.merge!(:includes => [ :comments ]).to_a
791
+ SpecialPost.all.merge!(includes: [ :comments ]).to_a
704
792
  end
705
793
 
706
794
  def test_eager_has_one_with_association_inheritance
707
- post = Post.all.merge!(:includes => [ :very_special_comment ]).find(4)
795
+ post = Post.all.merge!(includes: [ :very_special_comment ]).find(4)
708
796
  assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
709
797
  end
710
798
 
711
799
  def test_eager_has_many_with_association_inheritance
712
- post = Post.all.merge!(:includes => [ :special_comments ]).find(4)
800
+ post = Post.all.merge!(includes: [ :special_comments ]).find(4)
713
801
  post.special_comments.each do |special_comment|
714
802
  assert special_comment.is_a?(SpecialComment)
715
803
  end
716
804
  end
717
805
 
718
806
  def test_eager_habtm_with_association_inheritance
719
- post = Post.all.merge!(:includes => [ :special_categories ]).find(6)
807
+ post = Post.all.merge!(includes: [ :special_categories ]).find(6)
720
808
  assert_equal 1, post.special_categories.size
721
809
  post.special_categories.each do |special_category|
722
810
  assert_equal "SpecialCategory", special_category.class.to_s
@@ -725,8 +813,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
725
813
 
726
814
  def test_eager_with_has_one_dependent_does_not_destroy_dependent
727
815
  assert_not_nil companies(:first_firm).account
728
- f = Firm.all.merge!(:includes => :account,
729
- :where => ["companies.name = ?", "37signals"]).first
816
+ f = Firm.all.merge!(includes: :account,
817
+ where: ["companies.name = ?", "37signals"]).first
730
818
  assert_not_nil f.account
731
819
  assert_equal companies(:first_firm, :reload).account, f.account
732
820
  end
@@ -739,38 +827,54 @@ class EagerAssociationTest < ActiveRecord::TestCase
739
827
  end
740
828
 
741
829
  def test_eager_with_invalid_association_reference
742
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
743
- Post.all.merge!(:includes=> :monkeys ).find(6)
830
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
831
+ Post.all.merge!(includes: :monkeys).find(6)
744
832
  }
745
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
746
- Post.all.merge!(:includes=>[ :monkeys ]).find(6)
833
+ assert_match(/Association named 'monkeys' was not found on Post; perhaps you misspelled it\?/, e.message)
834
+
835
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
836
+ Post.all.merge!(includes: [ :monkeys ]).find(6)
747
837
  }
748
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
749
- Post.all.merge!(:includes=>[ 'monkeys' ]).find(6)
838
+ assert_match(/Association named 'monkeys' was not found on Post; perhaps you misspelled it\?/, e.message)
839
+
840
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
841
+ Post.all.merge!(includes: [ "monkeys" ]).find(6)
750
842
  }
751
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
752
- Post.all.merge!(:includes=>[ :monkeys, :elephants ]).find(6)
843
+ assert_match(/Association named 'monkeys' was not found on Post; perhaps you misspelled it\?/, e.message)
844
+
845
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
846
+ Post.all.merge!(includes: [ :monkeys, :elephants ]).find(6)
753
847
  }
848
+ assert_match(/Association named 'monkeys' was not found on Post; perhaps you misspelled it\?/, e.message)
849
+ end
850
+
851
+ if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
852
+ test "exceptions have suggestions for fix" do
853
+ error = assert_raise(ActiveRecord::AssociationNotFoundError) {
854
+ Post.all.merge!(includes: :monkeys).find(6)
855
+ }
856
+ assert_match "Did you mean?", error.message
857
+ end
754
858
  end
755
859
 
756
860
  def test_eager_has_many_through_with_order
757
- tag = OrderedTag.create(name: 'Foo')
758
- post1 = Post.create!(title: 'Beaches', body: "I like beaches!")
759
- post2 = Post.create!(title: 'Pools', body: "I like pools!")
861
+ tag = OrderedTag.create(name: "Foo")
862
+ post1 = Post.create!(title: "Beaches", body: "I like beaches!")
863
+ post2 = Post.create!(title: "Pools", body: "I like pools!")
760
864
 
761
- Tagging.create!(taggable_type: 'Post', taggable_id: post1.id, tag: tag)
762
- Tagging.create!(taggable_type: 'Post', taggable_id: post2.id, tag: tag)
865
+ Tagging.create!(taggable_type: "Post", taggable_id: post1.id, tag: tag)
866
+ Tagging.create!(taggable_type: "Post", taggable_id: post2.id, tag: tag)
763
867
 
764
868
  tag_with_includes = OrderedTag.includes(:tagged_posts).find(tag.id)
765
- assert_equal(tag_with_includes.taggings.map(&:taggable).map(&:title), tag_with_includes.tagged_posts.map(&:title))
869
+ assert_equal tag_with_includes.ordered_taggings.map(&:taggable).map(&:title), tag_with_includes.tagged_posts.map(&:title)
766
870
  end
767
871
 
768
872
  def test_eager_has_many_through_multiple_with_order
769
- tag1 = OrderedTag.create!(name: 'Bar')
770
- tag2 = OrderedTag.create!(name: 'Foo')
873
+ tag1 = OrderedTag.create!(name: "Bar")
874
+ tag2 = OrderedTag.create!(name: "Foo")
771
875
 
772
- post1 = Post.create!(title: 'Beaches', body: "I like beaches!")
773
- post2 = Post.create!(title: 'Pools', body: "I like pools!")
876
+ post1 = Post.create!(title: "Beaches", body: "I like beaches!")
877
+ post2 = Post.create!(title: "Pools", body: "I like pools!")
774
878
 
775
879
  Tagging.create!(taggable: post1, tag: tag1)
776
880
  Tagging.create!(taggable: post2, tag: tag1)
@@ -786,7 +890,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
786
890
  end
787
891
 
788
892
  def test_eager_with_default_scope
789
- developer = EagerDeveloperWithDefaultScope.where(:name => 'David').first
893
+ developer = EagerDeveloperWithDefaultScope.where(name: "David").first
790
894
  projects = Project.order(:id).to_a
791
895
  assert_no_queries do
792
896
  assert_equal(projects, developer.projects)
@@ -794,7 +898,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
794
898
  end
795
899
 
796
900
  def test_eager_with_default_scope_as_class_method
797
- developer = EagerDeveloperWithClassMethodDefaultScope.where(:name => 'David').first
901
+ developer = EagerDeveloperWithClassMethodDefaultScope.where(name: "David").first
798
902
  projects = Project.order(:id).to_a
799
903
  assert_no_queries do
800
904
  assert_equal(projects, developer.projects)
@@ -811,7 +915,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
811
915
  end
812
916
 
813
917
  def test_eager_with_default_scope_as_class_method_using_find_by_method
814
- developer = EagerDeveloperWithClassMethodDefaultScope.find_by(name: 'David')
918
+ developer = EagerDeveloperWithClassMethodDefaultScope.find_by(name: "David")
815
919
  projects = Project.order(:id).to_a
816
920
  assert_no_queries do
817
921
  assert_equal(projects, developer.projects)
@@ -819,7 +923,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
819
923
  end
820
924
 
821
925
  def test_eager_with_default_scope_as_lambda
822
- developer = EagerDeveloperWithLambdaDefaultScope.where(:name => 'David').first
926
+ developer = EagerDeveloperWithLambdaDefaultScope.where(name: "David").first
823
927
  projects = Project.order(:id).to_a
824
928
  assert_no_queries do
825
929
  assert_equal(projects, developer.projects)
@@ -828,8 +932,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
828
932
 
829
933
  def test_eager_with_default_scope_as_block
830
934
  # warm up the habtm cache
831
- EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first.projects
832
- developer = EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first
935
+ EagerDeveloperWithBlockDefaultScope.where(name: "David").first.projects
936
+ developer = EagerDeveloperWithBlockDefaultScope.where(name: "David").first
833
937
  projects = Project.order(:id).to_a
834
938
  assert_no_queries do
835
939
  assert_equal(projects, developer.projects)
@@ -837,108 +941,70 @@ class EagerAssociationTest < ActiveRecord::TestCase
837
941
  end
838
942
 
839
943
  def test_eager_with_default_scope_as_callable
840
- developer = EagerDeveloperWithCallableDefaultScope.where(:name => 'David').first
944
+ developer = EagerDeveloperWithCallableDefaultScope.where(name: "David").first
841
945
  projects = Project.order(:id).to_a
842
946
  assert_no_queries do
843
947
  assert_equal(projects, developer.projects)
844
948
  end
845
949
  end
846
950
 
847
- def find_all_ordered(className, include=nil)
848
- className.all.merge!(:order=>"#{className.table_name}.#{className.primary_key}", :includes=>include).to_a
849
- end
850
-
851
951
  def test_limited_eager_with_order
852
- unless current_adapter?(:IBM_DBAdapter)
853
- assert_equal(
854
- posts(:thinking, :sti_comments),
855
- Post.all.merge!(
856
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
857
- :order => 'UPPER(posts.title)', :limit => 2, :offset => 1
858
- ).to_a
859
- )
860
- assert_equal(
861
- posts(:sti_post_and_comments, :sti_comments),
862
- Post.all.merge!(
863
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
864
- :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1
865
- ).to_a
866
- )
867
- else
868
- assert_equal(
869
- posts(:thinking, :sti_comments),
870
- Post.all.merge!(
871
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
872
- :order => 'posts.id', :limit => 2, :offset => 1
873
- ).to_a
874
- )
875
- assert_equal(
876
- posts(:sti_post_and_comments, :sti_comments),
877
- Post.all.merge!(
878
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
879
- :order => 'posts.id DESC', :limit => 2, :offset => 1
880
- ).to_a
881
- )
882
- end
952
+ assert_equal(
953
+ posts(:thinking, :sti_comments),
954
+ Post.all.merge!(
955
+ includes: [:author, :comments], where: { "authors.name" => "David" },
956
+ order: "UPPER(posts.title)", limit: 2, offset: 1
957
+ ).to_a
958
+ )
959
+ assert_equal(
960
+ posts(:sti_post_and_comments, :sti_comments),
961
+ Post.all.merge!(
962
+ includes: [:author, :comments], where: { "authors.name" => "David" },
963
+ order: "UPPER(posts.title) DESC", limit: 2, offset: 1
964
+ ).to_a
965
+ )
883
966
  end
884
967
 
885
968
  def test_limited_eager_with_multiple_order_columns
886
- unless current_adapter?(:IBM_DBAdapter)
887
- assert_equal(
888
- posts(:thinking, :sti_comments),
889
- Post.all.merge!(
890
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
891
- :order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1
892
- ).to_a
893
- )
894
- assert_equal(
895
- posts(:sti_post_and_comments, :sti_comments),
896
- Post.all.merge!(
897
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
898
- :order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1
899
- ).to_a
900
- )
901
- else
902
- assert_equal(
903
- posts(:thinking, :sti_comments),
904
- Post.all.merge!(
905
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
906
- :order => ['posts.id'], :limit => 2, :offset => 1
907
- ).to_a
908
- )
909
- assert_equal(
910
- posts(:sti_post_and_comments, :sti_comments),
911
- Post.all.merge!(
912
- :includes => [:author, :comments], :where => { 'authors.name' => 'David' },
913
- :order => ['posts.id DESC'], :limit => 2, :offset => 1
914
- ).to_a
915
- )
916
- end
969
+ assert_equal(
970
+ posts(:thinking, :sti_comments),
971
+ Post.all.merge!(
972
+ includes: [:author, :comments], where: { "authors.name" => "David" },
973
+ order: ["UPPER(posts.title)", "posts.id"], limit: 2, offset: 1
974
+ ).to_a
975
+ )
976
+ assert_equal(
977
+ posts(:sti_post_and_comments, :sti_comments),
978
+ Post.all.merge!(
979
+ includes: [:author, :comments], where: { "authors.name" => "David" },
980
+ order: ["UPPER(posts.title) DESC", "posts.id"], limit: 2, offset: 1
981
+ ).to_a
982
+ )
917
983
  end
918
984
 
919
985
  def test_limited_eager_with_numeric_in_association
920
986
  assert_equal(
921
987
  people(:david, :susan),
922
988
  Person.references(:number1_fans_people).merge(
923
- :includes => [:readers, :primary_contact, :number1_fan],
924
- :where => "number1_fans_people.first_name like 'M%'",
925
- :order => 'people.id', :limit => 2, :offset => 0
989
+ includes: [:readers, :primary_contact, :number1_fan],
990
+ where: "number1_fans_people.first_name like 'M%'",
991
+ order: "people.id", limit: 2, offset: 0
926
992
  ).to_a
927
993
  )
928
994
  end
929
995
 
930
996
  def test_polymorphic_type_condition
931
- post = Post.all.merge!(:includes => :taggings).find(posts(:thinking).id)
932
- assert post.taggings.include?(taggings(:thinking_general))
933
- post = SpecialPost.all.merge!(:includes => :taggings).find(posts(:thinking).id)
934
- assert post.taggings.include?(taggings(:thinking_general))
997
+ post = Post.all.merge!(includes: :taggings).find(posts(:thinking).id)
998
+ assert_includes post.taggings, taggings(:thinking_general)
999
+ post = SpecialPost.all.merge!(includes: :taggings).find(posts(:thinking).id)
1000
+ assert_includes post.taggings, taggings(:thinking_general)
935
1001
  end
936
1002
 
937
1003
  def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
938
1004
  # Eager includes of has many and habtm associations aren't necessarily sorted in the same way
939
1005
  def assert_equal_after_sort(item1, item2, item3 = nil)
940
- assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
941
- assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
1006
+ assert_equal(item1.sort { |a, b| a.id <=> b.id }, item2.sort { |a, b| a.id <=> b.id })
1007
+ assert_equal(item3.sort { |a, b| a.id <=> b.id }, item2.sort { |a, b| a.id <=> b.id }) if item3
942
1008
  end
943
1009
  # Test regular association, association with conditions, association with
944
1010
  # STI, and association with conditions assured not to be true
@@ -956,7 +1022,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
956
1022
  d3 = find_all_ordered(className, [:posts, post_type])
957
1023
  assert_equal(d1[i], d3[i])
958
1024
  assert_equal_after_sort(d1[i].posts, d3[i].posts)
959
- assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
1025
+ assert_equal_after_sort(d1[i].public_send(post_type), d2[i].public_send(post_type), d3[i].public_send(post_type))
960
1026
  end
961
1027
  end
962
1028
  end
@@ -967,7 +1033,11 @@ class EagerAssociationTest < ActiveRecord::TestCase
967
1033
  d2 = find_all_ordered(Firm, :account)
968
1034
  d1.each_index do |i|
969
1035
  assert_equal(d1[i], d2[i])
970
- assert_equal(d1[i].account, d2[i].account)
1036
+ if d1[i].account.nil?
1037
+ assert_nil(d2[i].account)
1038
+ else
1039
+ assert_equal(d1[i].account, d2[i].account)
1040
+ end
971
1041
  end
972
1042
  end
973
1043
 
@@ -977,28 +1047,34 @@ class EagerAssociationTest < ActiveRecord::TestCase
977
1047
  d2 = find_all_ordered(Client, firm_types)
978
1048
  d1.each_index do |i|
979
1049
  assert_equal(d1[i], d2[i])
980
- firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
1050
+ firm_types.each do |type|
1051
+ if (expected = d1[i].public_send(type)).nil?
1052
+ assert_nil(d2[i].public_send(type))
1053
+ else
1054
+ assert_equal(expected, d2[i].public_send(type))
1055
+ end
1056
+ end
981
1057
  end
982
1058
  end
983
1059
  def test_eager_with_valid_association_as_string_not_symbol
984
- assert_nothing_raised { Post.all.merge!(:includes => 'comments').to_a }
1060
+ assert_nothing_raised { Post.all.merge!(includes: "comments").to_a }
985
1061
  end
986
1062
 
987
1063
  def test_eager_with_floating_point_numbers
988
1064
  assert_queries(2) do
989
1065
  # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
990
- Comment.all.merge!(:where => "123.456 = 123.456", :includes => :post).to_a
1066
+ Comment.all.merge!(where: "123.456 = 123.456", includes: :post).to_a
991
1067
  end
992
1068
  end
993
1069
 
994
1070
  def test_preconfigured_includes_with_belongs_to
995
1071
  author = posts(:welcome).author_with_posts
996
- assert_no_queries {assert_equal 5, author.posts.size}
1072
+ assert_no_queries { assert_equal 5, author.posts.size }
997
1073
  end
998
1074
 
999
1075
  def test_preconfigured_includes_with_has_one
1000
1076
  comment = posts(:sti_comments).very_special_comment_with_post
1001
- assert_no_queries {assert_equal posts(:sti_comments), comment.post}
1077
+ assert_no_queries { assert_equal posts(:sti_comments), comment.post }
1002
1078
  end
1003
1079
 
1004
1080
  def test_eager_association_with_scope_with_joins
@@ -1040,13 +1116,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
1040
1116
  end
1041
1117
 
1042
1118
  def test_association_loading_notification
1043
- notifications = messages_for('instantiation.active_record') do
1044
- Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
1119
+ notifications = messages_for("instantiation.active_record") do
1120
+ Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size
1045
1121
  end
1046
1122
 
1047
1123
  message = notifications.first
1048
1124
  payload = message.last
1049
- count = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
1125
+ count = Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size
1050
1126
 
1051
1127
  # eagerloaded row count should be greater than just developer count
1052
1128
  assert_operator payload[:record_count], :>, count
@@ -1054,7 +1130,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1054
1130
  end
1055
1131
 
1056
1132
  def test_base_messages
1057
- notifications = messages_for('instantiation.active_record') do
1133
+ notifications = messages_for("instantiation.active_record") do
1058
1134
  Developer.all.to_a
1059
1135
  end
1060
1136
  message = notifications.first
@@ -1076,61 +1152,55 @@ class EagerAssociationTest < ActiveRecord::TestCase
1076
1152
  end
1077
1153
 
1078
1154
  def test_load_with_sti_sharing_association
1079
- assert_queries(2) do #should not do 1 query per subclass
1155
+ assert_queries(2) do # should not do 1 query per subclass
1080
1156
  Comment.includes(:post).to_a
1081
1157
  end
1082
1158
  end
1083
1159
 
1084
1160
  def test_conditions_on_join_table_with_include_and_limit
1085
- assert_equal 3, Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
1161
+ assert_equal 3, Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size
1086
1162
  end
1087
1163
 
1088
1164
  def test_dont_create_temporary_active_record_instances
1089
1165
  Developer.instance_count = 0
1090
- developers = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a
1166
+ developers = Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a
1091
1167
  assert_equal developers.count, Developer.instance_count
1092
1168
  end
1093
1169
 
1094
1170
  def test_order_on_join_table_with_include_and_limit
1095
- assert_equal 5, Developer.all.merge!(:includes => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).to_a.size
1171
+ assert_equal 5, Developer.all.merge!(includes: "projects", order: "developers_projects.joined_on DESC", limit: 5).to_a.size
1096
1172
  end
1097
1173
 
1098
1174
  def test_eager_loading_with_order_on_joined_table_preloads
1099
1175
  posts = assert_queries(2) do
1100
- Post.all.merge!(:joins => :comments, :includes => :author, :order => 'comments.id DESC').to_a
1176
+ Post.all.merge!(joins: :comments, includes: :author, order: "comments.id DESC").to_a
1101
1177
  end
1102
- assert_equal posts(:eager_other), posts[1]
1103
- assert_equal authors(:mary), assert_no_queries { posts[1].author}
1178
+ assert_equal posts(:eager_other), posts[2]
1179
+ assert_equal authors(:mary), assert_no_queries { posts[2].author }
1104
1180
  end
1105
1181
 
1106
1182
  def test_eager_loading_with_conditions_on_joined_table_preloads
1107
1183
  posts = assert_queries(2) do
1108
- Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
1109
- end
1110
- assert_equal [posts(:welcome)], posts
1111
- assert_equal authors(:david), assert_no_queries { posts[0].author}
1112
-
1113
- posts = assert_queries(2) do
1114
- Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
1184
+ Post.all.merge!(select: "distinct posts.*", includes: :author, joins: [:comments], where: "comments.body like 'Thank you%'", order: "posts.id").to_a
1115
1185
  end
1116
1186
  assert_equal [posts(:welcome)], posts
1117
- assert_equal authors(:david), assert_no_queries { posts[0].author}
1187
+ assert_equal authors(:david), assert_no_queries { posts[0].author }
1118
1188
 
1119
1189
  posts = assert_queries(2) do
1120
- Post.all.merge!(:includes => :author, :joins => {:taggings => :tag}, :where => "tags.name = 'General'", :order => 'posts.id').to_a
1190
+ Post.all.merge!(includes: :author, joins: { taggings: :tag }, where: "tags.name = 'General'", order: "posts.id").to_a
1121
1191
  end
1122
1192
  assert_equal posts(:welcome, :thinking), posts
1123
1193
 
1124
1194
  posts = assert_queries(2) do
1125
- Post.all.merge!(:includes => :author, :joins => {:taggings => {:tag => :taggings}}, :where => "taggings_tags.super_tag_id=2", :order => 'posts.id').to_a
1195
+ Post.all.merge!(includes: :author, joins: { taggings: { tag: :taggings } }, where: "taggings_tags.super_tag_id=2", order: "posts.id").to_a
1126
1196
  end
1127
1197
  assert_equal posts(:welcome, :thinking), posts
1128
1198
  end
1129
1199
 
1130
1200
  def test_preload_has_many_with_association_condition_and_default_scope
1131
- post = Post.create!(:title => 'Beaches', :body => "I like beaches!")
1132
- Reader.create! :person => people(:david), :post => post
1133
- LazyReader.create! :person => people(:susan), :post => post
1201
+ post = Post.create!(title: "Beaches", body: "I like beaches!")
1202
+ Reader.create! person: people(:david), post: post
1203
+ LazyReader.create! person: people(:susan), post: post
1134
1204
 
1135
1205
  assert_equal 1, post.lazy_readers.to_a.size
1136
1206
  assert_equal 2, post.lazy_readers_skimmers_or_not.to_a.size
@@ -1141,69 +1211,62 @@ class EagerAssociationTest < ActiveRecord::TestCase
1141
1211
 
1142
1212
  def test_eager_loading_with_conditions_on_string_joined_table_preloads
1143
1213
  posts = assert_queries(2) do
1144
- Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => "INNER JOIN comments on comments.post_id = posts.id", :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
1214
+ Post.all.merge!(select: "distinct posts.*", includes: :author, joins: "INNER JOIN comments on comments.post_id = posts.id", where: "comments.body like 'Thank you%'", order: "posts.id").to_a
1145
1215
  end
1146
1216
  assert_equal [posts(:welcome)], posts
1147
- assert_equal authors(:david), assert_no_queries { posts[0].author}
1217
+ assert_equal authors(:david), assert_no_queries { posts[0].author }
1148
1218
 
1149
1219
  posts = assert_queries(2) do
1150
- Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => ["INNER JOIN comments on comments.post_id = posts.id"], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a
1220
+ Post.all.merge!(select: "distinct posts.*", includes: :author, joins: ["INNER JOIN comments on comments.post_id = posts.id"], where: "comments.body like 'Thank you%'", order: "posts.id").to_a
1151
1221
  end
1152
1222
  assert_equal [posts(:welcome)], posts
1153
- assert_equal authors(:david), assert_no_queries { posts[0].author}
1223
+ assert_equal authors(:david), assert_no_queries { posts[0].author }
1154
1224
  end
1155
1225
 
1156
1226
  def test_eager_loading_with_select_on_joined_table_preloads
1157
1227
  posts = assert_queries(2) do
1158
- Post.all.merge!(:select => 'posts.*, authors.name as author_name', :includes => :comments, :joins => :author, :order => 'posts.id').to_a
1228
+ Post.all.merge!(select: "posts.*, authors.name as author_name", includes: :comments, joins: :author, order: "posts.id").to_a
1159
1229
  end
1160
- assert_equal 'David', posts[0].author_name
1161
- assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments}
1230
+ assert_equal "David", posts[0].author_name
1231
+ assert_equal posts(:welcome).comments.sort_by(&:id), assert_no_queries { posts[0].comments.sort_by(&:id) }
1162
1232
  end
1163
1233
 
1164
1234
  def test_eager_loading_with_conditions_on_join_model_preloads
1165
1235
  authors = assert_queries(2) do
1166
- Author.all.merge!(:includes => :author_address, :joins => :comments, :where => "posts.title like 'Welcome%'").to_a
1236
+ Author.all.merge!(includes: :author_address, joins: :comments, where: "posts.title like 'Welcome%'").to_a
1167
1237
  end
1168
1238
  assert_equal authors(:david), authors[0]
1169
1239
  assert_equal author_addresses(:david_address), authors[0].author_address
1170
1240
  end
1171
1241
 
1172
1242
  def test_preload_belongs_to_uses_exclusive_scope
1173
- people = Person.males.merge(:includes => :primary_contact).to_a
1174
- assert_not_equal people.length, 0
1243
+ people = Person.males.includes(:primary_contact).to_a
1244
+ assert_equal 2, people.length
1175
1245
  people.each do |person|
1176
- assert_no_queries {assert_not_nil person.primary_contact}
1246
+ assert_no_queries { assert_not_nil person.primary_contact }
1177
1247
  assert_equal Person.find(person.id).primary_contact, person.primary_contact
1178
1248
  end
1179
1249
  end
1180
1250
 
1181
1251
  def test_preload_has_many_uses_exclusive_scope
1182
1252
  people = Person.males.includes(:agents).to_a
1253
+ assert_equal 2, people.length
1183
1254
  people.each do |person|
1184
- assert_equal Person.find(person.id).agents, person.agents
1255
+ assert_equal Person.find(person.id).agents.sort_by(&:id), person.agents.sort_by(&:id)
1185
1256
  end
1186
1257
  end
1187
1258
 
1188
1259
  def test_preload_has_many_using_primary_key
1189
- expected = Firm.first.clients_using_primary_key.to_a
1260
+ expected = Firm.first.clients_using_primary_key.sort_by(&:id)
1190
1261
  firm = Firm.includes(:clients_using_primary_key).first
1191
1262
  assert_no_queries do
1192
- assert_equal expected, firm.clients_using_primary_key
1263
+ assert_equal expected, firm.clients_using_primary_key.sort_by(&:id)
1193
1264
  end
1194
1265
  end
1195
1266
 
1196
1267
  def test_include_has_many_using_primary_key
1197
1268
  expected = Firm.find(1).clients_using_primary_key.sort_by(&:name)
1198
- # Oracle adapter truncates alias to 30 characters
1199
- if current_adapter?(:OracleAdapter)
1200
- firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies'[0,30]+'.name').find(1)
1201
- elsif current_adapter?(:IBM_DBAdapter)
1202
- #firm = Firm.all.merge!(:includes => :clients_using_primary_key).find(1)
1203
- firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name').find(1)
1204
- else
1205
- firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name').find(1)
1206
- end
1269
+ firm = Firm.all.merge!(includes: :clients_using_primary_key, order: "clients_using_primary_keys_companies.name").find(1)
1207
1270
  assert_no_queries do
1208
1271
  assert_equal expected, firm.clients_using_primary_key
1209
1272
  end
@@ -1211,7 +1274,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1211
1274
 
1212
1275
  def test_preload_has_one_using_primary_key
1213
1276
  expected = accounts(:signals37)
1214
- firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'companies.id').first
1277
+ firm = Firm.all.merge!(includes: :account_using_primary_key, order: "companies.id").first
1215
1278
  assert_no_queries do
1216
1279
  assert_equal expected, firm.account_using_primary_key
1217
1280
  end
@@ -1219,35 +1282,37 @@ class EagerAssociationTest < ActiveRecord::TestCase
1219
1282
 
1220
1283
  def test_include_has_one_using_primary_key
1221
1284
  expected = accounts(:signals37)
1222
- firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'accounts.id').to_a.detect {|f| f.id == 1}
1285
+ firm = Firm.all.merge!(includes: :account_using_primary_key, order: "accounts.id").to_a.detect { |f| f.id == 1 }
1223
1286
  assert_no_queries do
1224
1287
  assert_equal expected, firm.account_using_primary_key
1225
1288
  end
1226
1289
  end
1227
1290
 
1228
1291
  def test_preloading_empty_belongs_to
1229
- c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
1292
+ c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1)
1230
1293
 
1231
1294
  client = assert_queries(2) { Client.preload(:firm).find(c.id) }
1232
1295
  assert_no_queries { assert_nil client.firm }
1296
+ assert_equal c.client_of, client.client_of
1233
1297
  end
1234
1298
 
1235
1299
  def test_preloading_empty_belongs_to_polymorphic
1236
- t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general))
1300
+ t = Tagging.create!(taggable_type: "Post", taggable_id: Post.maximum(:id) + 1, tag: tags(:general))
1237
1301
 
1238
1302
  tagging = assert_queries(2) { Tagging.preload(:taggable).find(t.id) }
1239
1303
  assert_no_queries { assert_nil tagging.taggable }
1304
+ assert_equal t.taggable_id, tagging.taggable_id
1240
1305
  end
1241
1306
 
1242
1307
  def test_preloading_through_empty_belongs_to
1243
- c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
1308
+ c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1)
1244
1309
 
1245
1310
  client = assert_queries(2) { Client.preload(:accounts).find(c.id) }
1246
1311
  assert_no_queries { assert client.accounts.empty? }
1247
1312
  end
1248
1313
 
1249
1314
  def test_preloading_has_many_through_with_distinct
1250
- mary = Author.includes(:unique_categorized_posts).where(:id => authors(:mary).id).first
1315
+ mary = Author.includes(:unique_categorized_posts).where(id: authors(:mary).id).first
1251
1316
  assert_equal 1, mary.unique_categorized_posts.length
1252
1317
  assert_equal 1, mary.unique_categorized_post_ids.length
1253
1318
  end
@@ -1275,31 +1340,31 @@ class EagerAssociationTest < ActiveRecord::TestCase
1275
1340
  groucho = members(:groucho)
1276
1341
 
1277
1342
  sponsor = assert_queries(2) {
1278
- Sponsor.includes(:thing).where(:id => sponsor.id).first
1343
+ Sponsor.includes(:thing).where(id: sponsor.id).first
1279
1344
  }
1280
1345
  assert_no_queries { assert_equal groucho, sponsor.thing }
1281
1346
  end
1282
1347
 
1283
1348
  def test_joins_with_includes_should_preload_via_joins
1284
- post = assert_queries(1) { Post.includes(:comments).joins(:comments).order('posts.id desc').to_a.first }
1349
+ post = assert_queries(1) { Post.includes(:comments).joins(:comments).order("posts.id desc").to_a.first }
1285
1350
 
1286
- assert_queries(0) do
1351
+ assert_no_queries do
1287
1352
  assert_not_equal 0, post.comments.to_a.count
1288
1353
  end
1289
1354
  end
1290
1355
 
1291
1356
  def test_join_eager_with_empty_order_should_generate_valid_sql
1292
1357
  assert_nothing_raised do
1293
- Post.includes(:comments).order("").where(:comments => {:body => "Thank you for the welcome"}).first
1358
+ Post.includes(:comments).order("").where(comments: { body: "Thank you for the welcome" }).first
1294
1359
  end
1295
1360
  end
1296
1361
 
1297
1362
  def test_deep_including_through_habtm
1298
1363
  # warm up habtm cache
1299
- posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a
1364
+ posts = Post.all.merge!(includes: { categories: :categorizations }, order: "posts.id").to_a
1300
1365
  posts[0].categories[0].categorizations.length
1301
1366
 
1302
- posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a
1367
+ posts = Post.all.merge!(includes: { categories: :categorizations }, order: "posts.id").to_a
1303
1368
  assert_no_queries { assert_equal 2, posts[0].categories[0].categorizations.length }
1304
1369
  assert_no_queries { assert_equal 1, posts[0].categories[1].categorizations.length }
1305
1370
  assert_no_queries { assert_equal 2, posts[1].categories[0].categorizations.length }
@@ -1315,21 +1380,39 @@ class EagerAssociationTest < ActiveRecord::TestCase
1315
1380
  assert_equal projects.last.mentor.developers.first.contracts, projects.last.developers.last.contracts
1316
1381
  end
1317
1382
 
1383
+ def test_preloading_has_many_through_with_custom_scope
1384
+ project = Project.includes(:developers_named_david_with_hash_conditions).find(projects(:active_record).id)
1385
+ assert_equal [developers(:david)], project.developers_named_david_with_hash_conditions
1386
+ end
1387
+
1318
1388
  test "scoping with a circular preload" do
1319
- assert_equal Comment.find(1), Comment.preload(:post => :comments).scoping { Comment.find(1) }
1389
+ assert_equal Comment.find(1), Comment.preload(post: :comments).scoping { Comment.find(1) }
1320
1390
  end
1321
1391
 
1322
1392
  test "circular preload does not modify unscoped" do
1323
1393
  expected = FirstPost.unscoped.find(2)
1324
- FirstPost.preload(:comments => :first_post).find(1)
1394
+ FirstPost.preload(comments: :first_post).find(1)
1325
1395
  assert_equal expected, FirstPost.unscoped.find(2)
1326
1396
  end
1327
1397
 
1328
- test "preload ignores the scoping" do
1329
- assert_equal(
1330
- Comment.find(1).post,
1331
- Post.where('1 = 0').scoping { Comment.preload(:post).find(1).post }
1332
- )
1398
+ test "belongs_to association ignores the scoping" do
1399
+ post = Comment.find(1).post
1400
+
1401
+ Post.where("1=0").scoping do
1402
+ assert_equal post, Comment.find(1).post
1403
+ assert_equal post, Comment.preload(:post).find(1).post
1404
+ assert_equal post, Comment.eager_load(:post).find(1).post
1405
+ end
1406
+ end
1407
+
1408
+ test "has_many association ignores the scoping" do
1409
+ comments = Post.find(1).comments.to_a
1410
+
1411
+ Comment.where("1=0").scoping do
1412
+ assert_equal comments, Post.find(1).comments
1413
+ assert_equal comments, Post.preload(:comments).find(1).comments
1414
+ assert_equal comments, Post.eager_load(:comments).find(1).comments
1415
+ end
1333
1416
  end
1334
1417
 
1335
1418
  test "deep preload" do
@@ -1353,10 +1436,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
1353
1436
  end
1354
1437
 
1355
1438
  test "works in combination with order(:symbol) and reorder(:symbol)" do
1356
- author = Author.includes(:posts).references(:posts).order(:name).find_by('posts.title IS NOT NULL')
1439
+ author = Author.includes(:posts).references(:posts).order(:name).find_by("posts.title IS NOT NULL")
1357
1440
  assert_equal authors(:bob), author
1358
1441
 
1359
- author = Author.includes(:posts).references(:posts).reorder(:name).find_by('posts.title IS NOT NULL')
1442
+ author = Author.includes(:posts).references(:posts).reorder(:name).find_by("posts.title IS NOT NULL")
1360
1443
  assert_equal authors(:bob), author
1361
1444
  end
1362
1445
 
@@ -1382,6 +1465,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
1382
1465
 
1383
1466
  assert_nothing_raised do
1384
1467
  authors(:david).essays.includes(:writer).any?
1468
+ authors(:david).essays.includes(:writer).exists?
1469
+ authors(:david).essays.includes(:owner).where("name IS NOT NULL").exists?
1385
1470
  end
1386
1471
  end
1387
1472
 
@@ -1396,7 +1481,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1396
1481
 
1397
1482
  test "including associations with where.not adds implicit references" do
1398
1483
  author = assert_queries(2) {
1399
- Author.includes(:posts).where.not(posts: { title: 'Welcome to the weblog'} ).last
1484
+ Author.includes(:posts).where.not(posts: { title: "Welcome to the weblog" }).last
1400
1485
  }
1401
1486
 
1402
1487
  assert_no_queries {
@@ -1426,11 +1511,29 @@ class EagerAssociationTest < ActiveRecord::TestCase
1426
1511
  assert_match message, error.message
1427
1512
  end
1428
1513
 
1514
+ test "preloading and eager loading of optional instance dependent associations is not supported" do
1515
+ message = "association scope 'posts_mentioning_author' is"
1516
+ error = assert_raises(ArgumentError) do
1517
+ Author.includes(:posts_mentioning_author).to_a
1518
+ end
1519
+ assert_match message, error.message
1520
+
1521
+ error = assert_raises(ArgumentError) do
1522
+ Author.preload(:posts_mentioning_author).to_a
1523
+ end
1524
+ assert_match message, error.message
1525
+
1526
+ error = assert_raises(ArgumentError) do
1527
+ Author.eager_load(:posts_mentioning_author).to_a
1528
+ end
1529
+ assert_match message, error.message
1530
+ end
1531
+
1429
1532
  test "preload with invalid argument" do
1430
1533
  exception = assert_raises(ArgumentError) do
1431
1534
  Author.preload(10).to_a
1432
1535
  end
1433
- assert_equal('10 was not recognized for preload', exception.message)
1536
+ assert_equal("10 was not recognized for preload", exception.message)
1434
1537
  end
1435
1538
 
1436
1539
  test "associations with extensions are not instance dependent" do
@@ -1449,66 +1552,107 @@ class EagerAssociationTest < ActiveRecord::TestCase
1449
1552
  test "preloading readonly association" do
1450
1553
  # has-one
1451
1554
  firm = Firm.where(id: "1").preload(:readonly_account).first!
1452
- assert firm.readonly_account.readonly?
1555
+ assert_predicate firm.readonly_account, :readonly?
1453
1556
 
1454
1557
  # has_and_belongs_to_many
1455
1558
  project = Project.where(id: "2").preload(:readonly_developers).first!
1456
- assert project.readonly_developers.first.readonly?
1559
+ assert_predicate project.readonly_developers.first, :readonly?
1457
1560
 
1458
1561
  # has-many :through
1459
1562
  david = Author.where(id: "1").preload(:readonly_comments).first!
1460
- assert david.readonly_comments.first.readonly?
1563
+ assert_predicate david.readonly_comments.first, :readonly?
1461
1564
  end
1462
1565
 
1463
1566
  test "eager-loading non-readonly association" do
1464
1567
  # has_one
1465
1568
  firm = Firm.where(id: "1").eager_load(:account).first!
1466
- assert_not firm.account.readonly?
1569
+ assert_not_predicate firm.account, :readonly?
1467
1570
 
1468
1571
  # has_and_belongs_to_many
1469
1572
  project = Project.where(id: "2").eager_load(:developers).first!
1470
- assert_not project.developers.first.readonly?
1573
+ assert_not_predicate project.developers.first, :readonly?
1471
1574
 
1472
1575
  # has_many :through
1473
1576
  david = Author.where(id: "1").eager_load(:comments).first!
1474
- assert_not david.comments.first.readonly?
1577
+ assert_not_predicate david.comments.first, :readonly?
1475
1578
 
1476
1579
  # belongs_to
1477
1580
  post = Post.where(id: "1").eager_load(:author).first!
1478
- assert_not post.author.readonly?
1581
+ assert_not_predicate post.author, :readonly?
1479
1582
  end
1480
1583
 
1481
1584
  test "eager-loading readonly association" do
1482
1585
  # has-one
1483
1586
  firm = Firm.where(id: "1").eager_load(:readonly_account).first!
1484
- assert firm.readonly_account.readonly?
1587
+ assert_predicate firm.readonly_account, :readonly?
1485
1588
 
1486
1589
  # has_and_belongs_to_many
1487
1590
  project = Project.where(id: "2").eager_load(:readonly_developers).first!
1488
- assert project.readonly_developers.first.readonly?
1591
+ assert_predicate project.readonly_developers.first, :readonly?
1489
1592
 
1490
1593
  # has-many :through
1491
1594
  david = Author.where(id: "1").eager_load(:readonly_comments).first!
1492
- assert david.readonly_comments.first.readonly?
1595
+ assert_predicate david.readonly_comments.first, :readonly?
1493
1596
 
1494
1597
  # belongs_to
1495
1598
  post = Post.where(id: "1").eager_load(:readonly_author).first!
1496
- assert post.readonly_author.readonly?
1599
+ assert_predicate post.readonly_author, :readonly?
1497
1600
  end
1498
1601
 
1499
1602
  test "preloading a polymorphic association with references to the associated table" do
1500
- post = Post.includes(:tags).references(:tags).where('tags.name = ?', 'General').first
1603
+ post = Post.includes(:tags).references(:tags).where("tags.name = ?", "General").first
1501
1604
  assert_equal posts(:welcome), post
1502
1605
  end
1503
1606
 
1504
1607
  test "eager-loading a polymorphic association with references to the associated table" do
1505
- post = Post.eager_load(:tags).where('tags.name = ?', 'General').first
1608
+ post = Post.eager_load(:tags).where("tags.name = ?", "General").first
1506
1609
  assert_equal posts(:welcome), post
1507
1610
  end
1508
1611
 
1612
+ test "eager-loading with a polymorphic association won't work consistently" do
1613
+ assert_raise(ActiveRecord::EagerLoadPolymorphicError) { authors(:david).essays.eager_load(:writer).to_a }
1614
+ assert_raise(ActiveRecord::EagerLoadPolymorphicError) { authors(:david).essays.eager_load(:writer).count }
1615
+ assert_raise(ActiveRecord::EagerLoadPolymorphicError) { authors(:david).essays.eager_load(:writer).exists? }
1616
+ end
1617
+
1509
1618
  # CollectionProxy#reader is expensive, so the preloader avoids calling it.
1510
1619
  test "preloading has_many_through association avoids calling association.reader" do
1511
- ActiveRecord::Associations::HasManyAssociation.any_instance.expects(:reader).never
1512
- Author.preload(:readonly_comments).first!
1620
+ assert_not_called_on_instance_of(ActiveRecord::Associations::HasManyAssociation, :reader) do
1621
+ Author.preload(:readonly_comments).first!
1622
+ end
1623
+ end
1624
+
1625
+ test "preloading through a polymorphic association doesn't require the association to exist" do
1626
+ sponsors = []
1627
+ assert_queries 5 do
1628
+ sponsors = Sponsor.where(sponsorable_id: 1).preload(sponsorable: [:post, :membership]).to_a
1629
+ end
1630
+ # check the preload worked
1631
+ assert_queries 0 do
1632
+ sponsors.map(&:sponsorable).map { |s| s.respond_to?(:posts) ? s.post.author : s.membership }
1633
+ end
1513
1634
  end
1635
+
1636
+ test "preloading a regular association through a polymorphic association doesn't require the association to exist on all types" do
1637
+ sponsors = []
1638
+ assert_queries 6 do
1639
+ sponsors = Sponsor.where(sponsorable_id: 1).preload(sponsorable: [{ post: :first_comment }, :membership]).to_a
1640
+ end
1641
+ # check the preload worked
1642
+ assert_queries 0 do
1643
+ sponsors.map(&:sponsorable).map { |s| s.respond_to?(:posts) ? s.post.author : s.membership }
1644
+ end
1645
+ end
1646
+
1647
+ test "preloading a regular association with a typo through a polymorphic association still raises" do
1648
+ # this test contains an intentional typo of first -> fist
1649
+ assert_raises(ActiveRecord::AssociationNotFoundError) do
1650
+ Sponsor.where(sponsorable_id: 1).preload(sponsorable: [{ post: :fist_comment }, :membership]).to_a
1651
+ end
1652
+ end
1653
+
1654
+ private
1655
+ def find_all_ordered(klass, include = nil)
1656
+ klass.order("#{klass.table_name}.#{klass.primary_key}").includes(include).to_a
1657
+ end
1514
1658
  end