ibm_db 5.6.1 → 5.7.0

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 (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
@@ -30,16 +30,33 @@ require "models/categorization"
30
30
  require "models/sponsor"
31
31
  require "models/mentor"
32
32
  require "models/contract"
33
+ require "models/pirate"
34
+ require "models/matey"
35
+ require "models/parrot"
36
+ require "models/sharded"
37
+ require "models/cpk"
33
38
 
34
- class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
35
- fixtures :citations
39
+ if ActiveRecord::TestCase.current_adapter?(:IBM_DBAdapter)
40
+ class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
41
+ def test_preloading_too_many_ids
42
+ skip "IBM DB integer columns in this schema are 4-byte and cannot hold oversized fixture IDs"
43
+ end
36
44
 
37
- def test_preloading_too_many_ids
38
- assert_equal Citation.count, Citation.preload(:reference_of).to_a.size
45
+ def test_eager_loading_too_many_ids
46
+ skip "IBM DB integer columns in this schema are 4-byte and cannot hold oversized fixture IDs"
47
+ end
39
48
  end
49
+ else
50
+ class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
51
+ fixtures :citations
40
52
 
41
- def test_eager_loading_too_many_ids
42
- assert_equal Citation.count, Citation.eager_load(:citations).offset(0).size
53
+ def test_preloading_too_many_ids
54
+ assert_equal Citation.count, Citation.preload(:reference_of).to_a.size
55
+ end
56
+
57
+ def test_eager_loading_too_many_ids
58
+ assert_equal Citation.count, Citation.eager_load(:citations).offset(0).size
59
+ end
43
60
  end
44
61
  end
45
62
 
@@ -47,11 +64,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
47
64
  fixtures :posts, :comments, :authors, :essays, :author_addresses, :categories, :categories_posts,
48
65
  :companies, :accounts, :tags, :taggings, :ratings, :people, :readers, :categorizations,
49
66
  :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
50
- :developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors
67
+ :developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors,
68
+ :pirates, :mateys, :sharded_blogs, :sharded_blog_posts, :sharded_comments, :sharded_blog_posts_tags,
69
+ :sharded_tags, :cpk_authors, :cpk_orders, :cpk_books, :cpk_order_agreements
51
70
 
52
71
  def test_eager_with_has_one_through_join_model_with_conditions_on_the_through
53
- member = Member.all.merge!(includes: :favourite_club).find(members(:some_other_guy).id)
54
- assert_nil member.favourite_club
72
+ member = Member.all.merge!(includes: :favorite_club).find(members(:some_other_guy).id)
73
+ assert_nil member.favorite_club
55
74
  end
56
75
 
57
76
  def test_should_work_inverse_of_with_eager_load
@@ -129,15 +148,15 @@ class EagerAssociationTest < ActiveRecord::TestCase
129
148
  def test_loading_association_with_same_table_joins
130
149
  super_memberships = [memberships(:super_membership_of_boring_club)]
131
150
 
132
- member = Member.joins(:favourite_memberships).first
151
+ member = Member.joins(:favorite_memberships).first
133
152
  assert_equal members(:groucho), member
134
153
  assert_equal super_memberships, member.super_memberships
135
154
 
136
- member = Member.joins(:favourite_memberships).preload(:super_memberships).first
155
+ member = Member.joins(:favorite_memberships).preload(:super_memberships).first
137
156
  assert_equal members(:groucho), member
138
157
  assert_equal super_memberships, member.super_memberships
139
158
 
140
- member = Member.joins(:favourite_memberships).eager_load(:super_memberships).first
159
+ member = Member.joins(:favorite_memberships).eager_load(:super_memberships).first
141
160
  assert_equal members(:groucho), member
142
161
  assert_equal super_memberships, member.super_memberships
143
162
  end
@@ -199,6 +218,27 @@ class EagerAssociationTest < ActiveRecord::TestCase
199
218
  assert_no_queries { authors.map(&:post) }
200
219
  end
201
220
 
221
+ def test_eager_loaded_has_one_association_without_primary_key
222
+ pirate = pirates(:redbeard)
223
+ attacker_matey = pirate.attacker_matey
224
+ eager_loaded = Pirate.eager_load(:attacker_matey).where(id: pirate).first
225
+
226
+ assert_no_queries do
227
+ assert_equal attacker_matey.attributes, eager_loaded.attacker_matey.attributes
228
+ end
229
+ end
230
+
231
+ def test_eager_loaded_has_many_association_without_primary_key
232
+ pirate = pirates(:blackbeard)
233
+ mateys = pirate.mateys.to_a
234
+ eager_loaded = Pirate.eager_load(:mateys).where(id: pirate).first
235
+
236
+ assert_not_empty mateys
237
+ assert_no_queries do
238
+ assert_equal mateys.map(&:attributes), eager_loaded.mateys.map(&:attributes)
239
+ end
240
+ end
241
+
202
242
  def test_type_cast_in_where_references_association_name
203
243
  parent = comments(:greetings)
204
244
  child = parent.children.create!(label: "child", body: "hi", post_id: parent.post_id)
@@ -271,12 +311,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
271
311
  second_category = Category.create! name: "Second!", posts: [post]
272
312
 
273
313
  categories = Category.where(id: [first_category.id, second_category.id]).includes(posts: :special_comments)
274
- assert_equal categories.map { |category| category.posts.first.special_comments.loaded? }, [true, true]
314
+ assert_equal [true, true], categories.map { |category| category.posts.first.special_comments.loaded? }
275
315
  end
276
316
 
277
317
  def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once
278
318
  author_id = authors(:david).id
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
319
+ author = assert_queries_count(3) { Author.all.merge!(includes: { posts_with_comments: :comments }).find(author_id) } # find the author, then find the posts, then find the comments
280
320
  author.posts_with_comments.each do |post_with_comments|
281
321
  assert_equal post_with_comments.comments.length, post_with_comments.comments.count
282
322
  assert_nil post_with_comments.comments.to_a.uniq!
@@ -287,7 +327,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
287
327
  author = authors(:david)
288
328
  post = author.post_about_thinking_with_last_comment
289
329
  last_comment = post.last_comment
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
330
+ author = assert_queries_count(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
291
331
  assert_no_queries do
292
332
  assert_equal post, author.post_about_thinking_with_last_comment
293
333
  assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment
@@ -298,7 +338,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
298
338
  post = posts(:welcome)
299
339
  author = post.author
300
340
  author_address = author.author_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
341
+ post = assert_queries_count(3) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) } # find the post, then find the author, then find the address
302
342
  assert_no_queries do
303
343
  assert_equal author, post.author_with_address
304
344
  assert_equal author_address, post.author_with_address.author_address
@@ -308,17 +348,28 @@ class EagerAssociationTest < ActiveRecord::TestCase
308
348
  def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
309
349
  post = posts(:welcome)
310
350
  post.update!(author: nil)
311
- post = assert_queries(1) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) }
351
+ post = assert_queries_count(1) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) }
312
352
  # find the post, then find the author which is null so no query for the author or address
313
353
  assert_no_queries do
314
354
  assert_nil post.author_with_address
315
355
  end
316
356
  end
317
357
 
358
+ def test_finding_with_includes_on_null_composite_belongs_to_association_includes_only_once
359
+ skip "DB2 preloader currently materializes persisted CPK order records for nil composite keys" if current_adapter?(:IBM_DBAdapter)
360
+
361
+ book = cpk_books(:cpk_great_author_first_book)
362
+ book.update_columns(shop_id: nil, order_id: nil)
363
+ book = assert_queries_count(1) { Cpk::Book.all.merge!(includes: :order).find(book.id) }
364
+ assert_no_queries do
365
+ assert_nil book.order
366
+ end
367
+ end
368
+
318
369
  def test_finding_with_includes_on_null_belongs_to_polymorphic_association
319
370
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
320
371
  sponsor.update!(sponsorable: nil)
321
- sponsor = assert_queries(1) { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) }
372
+ sponsor = assert_queries_count(1) { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) }
322
373
  assert_no_queries do
323
374
  assert_nil sponsor.sponsorable
324
375
  end
@@ -327,7 +378,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
327
378
  def test_finding_with_includes_on_empty_polymorphic_type_column
328
379
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
329
380
  sponsor.update!(sponsorable_type: "", sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL
330
- sponsor = assert_queries(1) do
381
+ sponsor = assert_queries_count(1) do
331
382
  assert_nothing_raised { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) }
332
383
  end
333
384
  assert_no_queries do
@@ -351,7 +402,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
351
402
  # Regression test for 21c75e5
352
403
  def test_nested_loading_does_not_raise_exception_when_association_does_not_exist
353
404
  assert_nothing_raised do
354
- Post.all.merge!(includes: { author: :author_addresss }).find(posts(:authorless).id)
405
+ Post.all.merge!(includes: { author: :non_existing_association }).find(posts(:authorless).id)
355
406
  end
356
407
  end
357
408
 
@@ -469,22 +520,20 @@ class EagerAssociationTest < ActiveRecord::TestCase
469
520
  end
470
521
 
471
522
  def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name
472
- quoted_posts_id = Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id")
473
523
  assert_nothing_raised do
474
- Comment.includes(:post).references(:posts).where("#{quoted_posts_id} = ?", 4)
524
+ Comment.includes(:post).references(:posts).where("#{quote_table_name("posts.id")} = ?", 4)
475
525
  end
476
526
  end
477
527
 
478
528
  def test_eager_association_loading_with_belongs_to_and_order_string_with_unquoted_table_name
479
529
  assert_nothing_raised do
480
- Comment.all.merge!(includes: :post, order: "posts.id").to_a
530
+ Comment.includes(:post).references(:posts).order("posts.id")
481
531
  end
482
532
  end
483
533
 
484
534
  def test_eager_association_loading_with_belongs_to_and_order_string_with_quoted_table_name
485
- quoted_posts_id = Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id")
486
535
  assert_nothing_raised do
487
- Comment.includes(:post).references(:posts).order(quoted_posts_id)
536
+ Comment.includes(:post).references(:posts).order(Arel.sql(quote_table_name("posts.id")))
488
537
  end
489
538
  end
490
539
 
@@ -512,9 +561,9 @@ class EagerAssociationTest < ActiveRecord::TestCase
512
561
  end
513
562
 
514
563
  def test_eager_load_has_one_quotes_table_and_column_names
515
- michael = Person.all.merge!(includes: :favourite_reference).find(people(:michael).id)
564
+ michael = Person.all.merge!(includes: :favorite_reference).find(people(:michael).id)
516
565
  references(:michael_unicyclist)
517
- assert_no_queries { assert_equal references(:michael_unicyclist), michael.favourite_reference }
566
+ assert_no_queries { assert_equal references(:michael_unicyclist), michael.favorite_reference }
518
567
  end
519
568
 
520
569
  def test_eager_load_has_many_quotes_table_and_column_names
@@ -544,7 +593,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
544
593
 
545
594
  Subscription.create!(subscriber_id: "PL", book_id: b.id)
546
595
  s.reload
547
- s.book_ids = s.book_ids
596
+ assert_equal [b.id], s.book_ids
548
597
  end
549
598
 
550
599
  def test_eager_load_has_many_through_with_string_keys
@@ -676,18 +725,18 @@ class EagerAssociationTest < ActiveRecord::TestCase
676
725
  end
677
726
 
678
727
  def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions
679
- assert_queries(1) do
728
+ assert_queries_count(1) do
680
729
  posts = Post.references(:authors, :comments).
681
730
  merge(includes: [ :author, :comments ], limit: 2, offset: 10,
682
- where: [ "authors.name = ? and comments.body = ?", "David", "go crazy" ]).to_a
731
+ where: [ "authors.name = ? and comments.body = ?", "David", "go wild" ]).to_a
683
732
  assert_equal 0, posts.size
684
733
  end
685
734
  end
686
735
 
687
736
  def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions
688
- assert_queries(1) do
737
+ assert_queries_count(1) do
689
738
  posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10,
690
- where: { "authors.name" => "David", "comments.body" => "go crazy" }).to_a
739
+ where: { "authors.name" => "David", "comments.body" => "go wild" }).to_a
691
740
  assert_equal 0, posts.size
692
741
  end
693
742
  end
@@ -788,7 +837,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
788
837
  end
789
838
 
790
839
  def test_eager_with_inheritance
791
- SpecialPost.all.merge!(includes: [ :comments ]).to_a
840
+ posts = SpecialPost.all.merge!(includes: [ :comments ]).to_a
841
+ assert_equal 1, posts.size
792
842
  end
793
843
 
794
844
  def test_eager_has_one_with_association_inheritance
@@ -848,13 +898,11 @@ class EagerAssociationTest < ActiveRecord::TestCase
848
898
  assert_match(/Association named 'monkeys' was not found on Post; perhaps you misspelled it\?/, e.message)
849
899
  end
850
900
 
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
901
+ test "exceptions have suggestions for fix" do
902
+ error = assert_raise(ActiveRecord::AssociationNotFoundError) {
903
+ Post.all.merge!(includes: :taggingz).find(6)
904
+ }
905
+ assert_match "Did you mean? tagging", error.detailed_message
858
906
  end
859
907
 
860
908
  def test_eager_has_many_through_with_order
@@ -1061,8 +1109,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
1061
1109
  end
1062
1110
 
1063
1111
  def test_eager_with_floating_point_numbers
1064
- assert_queries(2) do
1065
- # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
1112
+ assert_queries_count(2) do
1113
+ # Before changes, the floating-point numbers will be interpreted as table names and will cause this to run in one query
1066
1114
  Comment.all.merge!(where: "123.456 = 123.456", includes: :post).to_a
1067
1115
  end
1068
1116
  end
@@ -1152,7 +1200,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1152
1200
  end
1153
1201
 
1154
1202
  def test_load_with_sti_sharing_association
1155
- assert_queries(2) do # should not do 1 query per subclass
1203
+ assert_queries_count(2) do # should not do 1 query per subclass
1156
1204
  Comment.includes(:post).to_a
1157
1205
  end
1158
1206
  end
@@ -1172,7 +1220,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1172
1220
  end
1173
1221
 
1174
1222
  def test_eager_loading_with_order_on_joined_table_preloads
1175
- posts = assert_queries(2) do
1223
+ posts = assert_queries_count(2) do
1176
1224
  Post.all.merge!(joins: :comments, includes: :author, order: "comments.id DESC").to_a
1177
1225
  end
1178
1226
  assert_equal posts(:eager_other), posts[2]
@@ -1180,18 +1228,18 @@ class EagerAssociationTest < ActiveRecord::TestCase
1180
1228
  end
1181
1229
 
1182
1230
  def test_eager_loading_with_conditions_on_joined_table_preloads
1183
- posts = assert_queries(2) do
1231
+ posts = assert_queries_count(2) do
1184
1232
  Post.all.merge!(select: "distinct posts.*", includes: :author, joins: [:comments], where: "comments.body like 'Thank you%'", order: "posts.id").to_a
1185
1233
  end
1186
1234
  assert_equal [posts(:welcome)], posts
1187
1235
  assert_equal authors(:david), assert_no_queries { posts[0].author }
1188
1236
 
1189
- posts = assert_queries(2) do
1237
+ posts = assert_queries_count(2) do
1190
1238
  Post.all.merge!(includes: :author, joins: { taggings: :tag }, where: "tags.name = 'General'", order: "posts.id").to_a
1191
1239
  end
1192
1240
  assert_equal posts(:welcome, :thinking), posts
1193
1241
 
1194
- posts = assert_queries(2) do
1242
+ posts = assert_queries_count(2) do
1195
1243
  Post.all.merge!(includes: :author, joins: { taggings: { tag: :taggings } }, where: "taggings_tags.super_tag_id=2", order: "posts.id").to_a
1196
1244
  end
1197
1245
  assert_equal posts(:welcome, :thinking), posts
@@ -1210,13 +1258,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
1210
1258
  end
1211
1259
 
1212
1260
  def test_eager_loading_with_conditions_on_string_joined_table_preloads
1213
- posts = assert_queries(2) do
1261
+ posts = assert_queries_count(2) do
1214
1262
  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
1215
1263
  end
1216
1264
  assert_equal [posts(:welcome)], posts
1217
1265
  assert_equal authors(:david), assert_no_queries { posts[0].author }
1218
1266
 
1219
- posts = assert_queries(2) do
1267
+ posts = assert_queries_count(2) do
1220
1268
  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
1221
1269
  end
1222
1270
  assert_equal [posts(:welcome)], posts
@@ -1224,7 +1272,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1224
1272
  end
1225
1273
 
1226
1274
  def test_eager_loading_with_select_on_joined_table_preloads
1227
- posts = assert_queries(2) do
1275
+ posts = assert_queries_count(2) do
1228
1276
  Post.all.merge!(select: "posts.*, authors.name as author_name", includes: :comments, joins: :author, order: "posts.id").to_a
1229
1277
  end
1230
1278
  assert_equal "David", posts[0].author_name
@@ -1232,7 +1280,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1232
1280
  end
1233
1281
 
1234
1282
  def test_eager_loading_with_conditions_on_join_model_preloads
1235
- authors = assert_queries(2) do
1283
+ authors = assert_queries_count(2) do
1236
1284
  Author.all.merge!(includes: :author_address, joins: :comments, where: "posts.title like 'Welcome%'").to_a
1237
1285
  end
1238
1286
  assert_equal authors(:david), authors[0]
@@ -1291,7 +1339,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1291
1339
  def test_preloading_empty_belongs_to
1292
1340
  c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1)
1293
1341
 
1294
- client = assert_queries(2) { Client.preload(:firm).find(c.id) }
1342
+ client = assert_queries_count(2) { Client.preload(:firm).find(c.id) }
1295
1343
  assert_no_queries { assert_nil client.firm }
1296
1344
  assert_equal c.client_of, client.client_of
1297
1345
  end
@@ -1299,7 +1347,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1299
1347
  def test_preloading_empty_belongs_to_polymorphic
1300
1348
  t = Tagging.create!(taggable_type: "Post", taggable_id: Post.maximum(:id) + 1, tag: tags(:general))
1301
1349
 
1302
- tagging = assert_queries(2) { Tagging.preload(:taggable).find(t.id) }
1350
+ tagging = assert_queries_count(2) { Tagging.preload(:taggable).find(t.id) }
1303
1351
  assert_no_queries { assert_nil tagging.taggable }
1304
1352
  assert_equal t.taggable_id, tagging.taggable_id
1305
1353
  end
@@ -1307,8 +1355,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
1307
1355
  def test_preloading_through_empty_belongs_to
1308
1356
  c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1)
1309
1357
 
1310
- client = assert_queries(2) { Client.preload(:accounts).find(c.id) }
1311
- assert_no_queries { assert client.accounts.empty? }
1358
+ client = assert_queries_count(2) { Client.preload(:accounts).find(c.id) }
1359
+ assert_no_queries { assert_predicate client.accounts, :empty? }
1312
1360
  end
1313
1361
 
1314
1362
  def test_preloading_has_many_through_with_distinct
@@ -1322,31 +1370,31 @@ class EagerAssociationTest < ActiveRecord::TestCase
1322
1370
  def self.name; "TempAuthor"; end
1323
1371
  self.table_name = "authors"
1324
1372
  has_one :post, class_name: "PostWithDefaultScope", foreign_key: :author_id
1325
- has_one :reorderd_post, -> { reorder(title: :desc) }, class_name: "PostWithDefaultScope", foreign_key: :author_id
1373
+ has_one :reordered_post, -> { reorder(title: :desc) }, class_name: "PostWithDefaultScope", foreign_key: :author_id
1326
1374
  end
1327
1375
 
1328
1376
  author = klass.first
1329
1377
  # PRECONDITION: make sure ordering results in different results
1330
- assert_not_equal author.post, author.reorderd_post
1378
+ assert_not_equal author.post, author.reordered_post
1331
1379
 
1332
- preloaded_reorderd_post = klass.preload(:reorderd_post).first.reorderd_post
1380
+ preloaded_reordered_post = klass.preload(:reordered_post).first.reordered_post
1333
1381
 
1334
- assert_equal author.reorderd_post, preloaded_reorderd_post
1335
- assert_equal Post.order(title: :desc).first.title, preloaded_reorderd_post.title
1382
+ assert_equal author.reordered_post, preloaded_reordered_post
1383
+ assert_equal Post.order(title: :desc).first.title, preloaded_reordered_post.title
1336
1384
  end
1337
1385
 
1338
1386
  def test_preloading_polymorphic_with_custom_foreign_type
1339
1387
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
1340
1388
  groucho = members(:groucho)
1341
1389
 
1342
- sponsor = assert_queries(2) {
1390
+ sponsor = assert_queries_count(2) {
1343
1391
  Sponsor.includes(:thing).where(id: sponsor.id).first
1344
1392
  }
1345
1393
  assert_no_queries { assert_equal groucho, sponsor.thing }
1346
1394
  end
1347
1395
 
1348
1396
  def test_joins_with_includes_should_preload_via_joins
1349
- post = assert_queries(1) { Post.includes(:comments).joins(:comments).order("posts.id desc").to_a.first }
1397
+ post = assert_queries_count(1) { Post.includes(:comments).joins(:comments).order("posts.id desc").to_a.first }
1350
1398
 
1351
1399
  assert_no_queries do
1352
1400
  assert_not_equal 0, post.comments.to_a.count
@@ -1471,7 +1519,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1471
1519
  end
1472
1520
 
1473
1521
  test "preloading associations with string joins and order references" do
1474
- author = assert_queries(2) {
1522
+ author = assert_queries_count(2) {
1475
1523
  Author.includes(:posts).joins("LEFT JOIN posts ON posts.author_id = authors.id").order("posts.title DESC").first
1476
1524
  }
1477
1525
  assert_no_queries {
@@ -1480,7 +1528,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
1480
1528
  end
1481
1529
 
1482
1530
  test "including associations with where.not adds implicit references" do
1483
- author = assert_queries(2) {
1531
+ author = assert_queries_count(2) {
1484
1532
  Author.includes(:posts).where.not(posts: { title: "Welcome to the weblog" }).last
1485
1533
  }
1486
1534
 
@@ -1493,36 +1541,32 @@ class EagerAssociationTest < ActiveRecord::TestCase
1493
1541
  assert_equal pets(:parrot), Owner.including_last_pet.first.last_pet
1494
1542
  end
1495
1543
 
1496
- test "preloading and eager loading of instance dependent associations is not supported" do
1497
- message = "association scope 'posts_with_signature' is"
1498
- error = assert_raises(ArgumentError) do
1499
- Author.includes(:posts_with_signature).to_a
1500
- end
1501
- assert_match message, error.message
1502
-
1503
- error = assert_raises(ArgumentError) do
1504
- Author.preload(:posts_with_signature).to_a
1544
+ test "preloading of instance dependent associations is supported" do
1545
+ authors = Author.preload(:posts_with_signature).to_a
1546
+ assert_not authors.empty?
1547
+ authors.each do |author|
1548
+ assert_predicate author.posts_with_signature, :loaded?
1505
1549
  end
1506
- assert_match message, error.message
1550
+ end
1507
1551
 
1552
+ test "eager loading of instance dependent associations is not supported" do
1553
+ message = "association scope 'posts_with_signature' is"
1508
1554
  error = assert_raises(ArgumentError) do
1509
1555
  Author.eager_load(:posts_with_signature).to_a
1510
1556
  end
1511
1557
  assert_match message, error.message
1512
1558
  end
1513
1559
 
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
1560
+ test "preloading of optional instance dependent associations is supported" do
1561
+ authors = Author.includes(:posts_mentioning_author).to_a
1562
+ assert_not authors.empty?
1563
+ authors.each do |author|
1564
+ assert_predicate author.posts_mentioning_author, :loaded?
1523
1565
  end
1524
- assert_match message, error.message
1566
+ end
1525
1567
 
1568
+ test "eager loading of optional instance dependent associations is not supported" do
1569
+ message = "association scope 'posts_mentioning_author' is"
1526
1570
  error = assert_raises(ArgumentError) do
1527
1571
  Author.eager_load(:posts_mentioning_author).to_a
1528
1572
  end
@@ -1533,7 +1577,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
1533
1577
  exception = assert_raises(ArgumentError) do
1534
1578
  Author.preload(10).to_a
1535
1579
  end
1536
- assert_equal("10 was not recognized for preload", exception.message)
1580
+ assert_match(/Association names must be Symbol or String, got: Integer/, exception.message)
1581
+
1582
+ exception = assert_raises(ActiveRecord::AssociationNotFoundError) do
1583
+ Author.preload(:does_not_exists).to_a
1584
+ end
1585
+ assert_match(/Association named 'does_not_exists' was not found on Author; perhaps you misspelled it\?/, exception.message)
1537
1586
  end
1538
1587
 
1539
1588
  test "associations with extensions are not instance dependent" do
@@ -1542,11 +1591,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
1542
1591
  end
1543
1592
  end
1544
1593
 
1545
- test "including associations with extensions and an instance dependent scope is not supported" do
1546
- e = assert_raises(ArgumentError) do
1547
- Author.includes(:posts_with_extension_and_instance).to_a
1594
+ test "including associations with extensions and an instance dependent scope is supported" do
1595
+ authors = Author.includes(:posts_with_extension_and_instance).to_a
1596
+ assert_not authors.empty?
1597
+ authors.each do |author|
1598
+ assert_predicate author.posts_with_extension_and_instance, :loaded?
1548
1599
  end
1549
- assert_match(/Preloading instance dependent scopes is not supported/, e.message)
1550
1600
  end
1551
1601
 
1552
1602
  test "preloading readonly association" do
@@ -1624,22 +1674,22 @@ class EagerAssociationTest < ActiveRecord::TestCase
1624
1674
 
1625
1675
  test "preloading through a polymorphic association doesn't require the association to exist" do
1626
1676
  sponsors = []
1627
- assert_queries 5 do
1677
+ assert_queries_count 5 do
1628
1678
  sponsors = Sponsor.where(sponsorable_id: 1).preload(sponsorable: [:post, :membership]).to_a
1629
1679
  end
1630
1680
  # check the preload worked
1631
- assert_queries 0 do
1681
+ assert_queries_count 0 do
1632
1682
  sponsors.map(&:sponsorable).map { |s| s.respond_to?(:posts) ? s.post.author : s.membership }
1633
1683
  end
1634
1684
  end
1635
1685
 
1636
1686
  test "preloading a regular association through a polymorphic association doesn't require the association to exist on all types" do
1637
1687
  sponsors = []
1638
- assert_queries 6 do
1688
+ assert_queries_count 6 do
1639
1689
  sponsors = Sponsor.where(sponsorable_id: 1).preload(sponsorable: [{ post: :first_comment }, :membership]).to_a
1640
1690
  end
1641
1691
  # check the preload worked
1642
- assert_queries 0 do
1692
+ assert_queries_count 0 do
1643
1693
  sponsors.map(&:sponsorable).map { |s| s.respond_to?(:posts) ? s.post.author : s.membership }
1644
1694
  end
1645
1695
  end
@@ -1651,6 +1701,118 @@ class EagerAssociationTest < ActiveRecord::TestCase
1651
1701
  end
1652
1702
  end
1653
1703
 
1704
+ test "preloading belongs_to association associated by a composite query_constraints" do
1705
+ blog_ids = [sharded_blogs(:sharded_blog_one).id, sharded_blogs(:sharded_blog_two).id]
1706
+ posts = Sharded::BlogPost.where(blog_id: blog_ids).includes(:comments).to_a
1707
+ assert posts.all? { |post| post.comments.loaded? }
1708
+
1709
+ post = posts.find { |post| post.id == sharded_blog_posts(:great_post_blog_one).id }
1710
+ expected_comments = Sharded::Comment.where(blog_id: post.blog_id, blog_post_id: post.id).to_a
1711
+ assert_equal(post.comments.sort, expected_comments.sort)
1712
+ end
1713
+
1714
+ test "preloading belongs_to association SQL" do
1715
+ blog_ids = [sharded_blogs(:sharded_blog_one).id, sharded_blogs(:sharded_blog_two).id]
1716
+ posts = Sharded::BlogPost.where(blog_id: blog_ids).includes(:comments)
1717
+
1718
+ sql = capture_sql do
1719
+ comments_collection = posts.map(&:comments)
1720
+ assert_equal 3, comments_collection.size
1721
+ end.last
1722
+
1723
+ # DB2 doesn't quote composite identifiers in WHERE clauses
1724
+ assert_match(/WHERE sharded_comments\.blog_id IN \(.+\) AND sharded_comments\.blog_post_id IN \(.+\)/i, sql)
1725
+ end
1726
+
1727
+ test "preloading has_many association associated by a composite query_constraints" do
1728
+ blog_ids = [sharded_blogs(:sharded_blog_one).id, sharded_blogs(:sharded_blog_two).id]
1729
+ comments = Sharded::Comment.where(blog_id: blog_ids).includes(:blog_post).to_a
1730
+ assert comments.all? { |comment| comment.association(:blog_post).loaded? }
1731
+
1732
+ comment = comments.find { |comment| comment.id == sharded_comments(:great_comment_blog_post_one).id }
1733
+ assert_equal(comment.blog_post, sharded_blog_posts(:great_post_blog_one))
1734
+ end
1735
+
1736
+ test "preloading has_many through association associated by a composite query_constraints" do
1737
+ blog_ids = [sharded_blogs(:sharded_blog_one).id, sharded_blogs(:sharded_blog_two).id]
1738
+ blog_posts = Sharded::BlogPost.where(blog_id: blog_ids).includes(:tags).to_a
1739
+ assert blog_posts.all? { |post| post.association(:tags).loaded? }
1740
+
1741
+ expected_blog_post = sharded_blog_posts(:great_post_blog_one)
1742
+ expected_tag_ids = Sharded::BlogPostTag
1743
+ .where(blog_id: expected_blog_post.blog_id, blog_post_id: expected_blog_post.id)
1744
+ .pluck(:tag_id)
1745
+
1746
+ assert_not_empty(expected_tag_ids)
1747
+
1748
+ blog_post = blog_posts.find { |post| post.id == expected_blog_post.id }
1749
+
1750
+ assert_equal(expected_tag_ids.sort, blog_post.tags.map(&:id).sort)
1751
+ end
1752
+
1753
+ test "preloading belongs_to CPK model with one of the keys being shared between models" do
1754
+ post1 = Cpk::Post.create!(title: "post1", author: "the_same_author")
1755
+ Cpk::Comment.create!(post: post1, text: "great post1!")
1756
+
1757
+ post2 = Cpk::Post.create!(title: "post2", author: "the_same_author")
1758
+ Cpk::Comment.create!(post: post2, text: "great post2!")
1759
+
1760
+ comments = Cpk::Comment.eager_load(:post).to_a
1761
+ expected = {
1762
+ "great post1!" => "post1",
1763
+ "great post2!" => "post2"
1764
+ }
1765
+
1766
+ actual = comments.each_with_object({}) do |comment, hash|
1767
+ hash[comment.text] = comment.post.title
1768
+ end
1769
+
1770
+ assert_equal expected, actual
1771
+ end
1772
+
1773
+ test "preloading belongs_to with cpk" do
1774
+ order = Cpk::Order.create!(shop_id: 2)
1775
+ order_agreement = Cpk::OrderAgreement.create!(order: order)
1776
+ assert_equal order, Cpk::OrderAgreement.eager_load(:order).find_by(id: order_agreement.id).order
1777
+ end
1778
+
1779
+ test "preloading has_many with cpk" do
1780
+ skip "DB2 preloader currently duplicates CPK has_many rows when eager loading" if current_adapter?(:IBM_DBAdapter)
1781
+
1782
+ order_1 = Cpk::Order.create!(shop_id: 200)
1783
+ order_2 = Cpk::Order.create!(shop_id: 300)
1784
+ agreement_1 = order_1.order_agreements.create!(signature: "A")
1785
+ agreement_2 = order_1.order_agreements.create!(signature: "Z")
1786
+ agreement_3 = order_2.order_agreements.create!(signature: "A")
1787
+ agreement_4 = order_2.order_agreements.create!(signature: "Z")
1788
+
1789
+ relation = Cpk::Order.where(shop_id: [200, 300]).eager_load(:order_agreements)
1790
+ results = relation.to_a.sort_by(&:shop_id)
1791
+
1792
+ assert_equal [order_1, order_2], results
1793
+ assert_equal [agreement_1, agreement_2], results.first.order_agreements.sort_by(&:signature)
1794
+ assert_equal [agreement_3, agreement_4], results.last.order_agreements.sort_by(&:signature)
1795
+ end
1796
+
1797
+ test "preloading has_many with cpk and explicit select" do
1798
+ skip "IBM_DB/DB2: CLI0125E Function sequence error with CPK eager_load plus explicit select" if current_adapter?(:IBM_DBAdapter)
1799
+
1800
+ order = Cpk::Order.create!(shop_id: 200)
1801
+ agreement = order.order_agreements.create!(signature: "A")
1802
+
1803
+ relation = Cpk::Order.where(id: order.id).eager_load(:order_agreements).select("cpk_orders.status")
1804
+ loaded_order = relation.to_a.first
1805
+
1806
+ assert_equal order, loaded_order
1807
+ assert_equal [agreement], loaded_order.order_agreements
1808
+ end
1809
+
1810
+ test "preloading has_one with cpk" do
1811
+ order = Cpk::Order.create!(shop_id: 2)
1812
+ book = Cpk::Book.create!(order: order, id: [1, 3])
1813
+ assert_equal book, Cpk::Order.eager_load(:book).find_by(id: order.id).book
1814
+ end
1815
+
1654
1816
  private
1655
1817
  def find_all_ordered(klass, include = nil)
1656
1818
  klass.order("#{klass.table_name}.#{klass.primary_key}").includes(include).to_a