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
@@ -24,29 +24,23 @@ class RelationMergingTest < ActiveRecord::TestCase
24
24
 
25
25
  assert_equal [mary], david_and_mary.merge(Author.where(id: mary))
26
26
  assert_equal [mary], david_and_mary.merge(Author.rewhere(id: mary))
27
- assert_equal [mary], david_and_mary.merge(Author.where(id: mary), rewhere: true)
28
27
 
29
28
  assert_equal [bob], david_and_mary.merge(Author.where(id: bob))
30
29
  assert_equal [bob], david_and_mary.merge(Author.rewhere(id: bob))
31
- assert_equal [bob], david_and_mary.merge(Author.where(id: bob), rewhere: true)
32
30
 
33
31
  assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]))
34
- assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]), rewhere: true)
35
32
 
36
33
  assert_equal [mary, bob], david_and_mary.merge(mary_and_bob)
37
- assert_equal [mary, bob], david_and_mary.merge(mary_and_bob, rewhere: true)
38
34
  assert_equal [mary], david_and_mary.and(mary_and_bob)
39
35
  assert_equal authors, david_and_mary.or(mary_and_bob)
40
36
 
41
37
  assert_equal [david, mary], mary_and_bob.merge(david_and_mary)
42
- assert_equal [david, mary], mary_and_bob.merge(david_and_mary, rewhere: true)
43
38
  assert_equal [mary], david_and_mary.and(mary_and_bob)
44
39
  assert_equal authors, david_and_mary.or(mary_and_bob)
45
40
 
46
41
  david_and_bob = Author.where(id: david).or(Author.where(name: "Bob"))
47
42
 
48
43
  assert_equal [david], david_and_mary.merge(david_and_bob)
49
- assert_equal [david], david_and_mary.merge(david_and_bob, rewhere: true)
50
44
  assert_equal [david], david_and_mary.and(david_and_bob)
51
45
  assert_equal authors, david_and_mary.or(david_and_bob)
52
46
  end
@@ -60,46 +54,25 @@ class RelationMergingTest < ActiveRecord::TestCase
60
54
  assert_equal [david, mary], david_and_mary
61
55
  assert_equal [mary, bob], mary_and_bob
62
56
 
63
- author_id = Regexp.escape(Author.connection.quote_table_name("authors.id"))
64
- message = %r/Merging \(#{author_id} BETWEEN (\?|\W?\w?\d) AND \g<1>\) and \(#{author_id} (?:= \g<1>|IN \(\g<1>, \g<1>\))\) no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0\./
65
-
66
- assert_deprecated(message) do
67
- assert_equal [mary], david_and_mary.merge(Author.where(id: mary))
68
- end
57
+ assert_equal [mary], david_and_mary.merge(Author.where(id: mary))
69
58
  assert_equal [mary], david_and_mary.merge(Author.rewhere(id: mary))
70
- assert_equal [mary], david_and_mary.merge(Author.where(id: mary), rewhere: true)
71
59
 
72
- assert_deprecated(message) do
73
- assert_equal [], david_and_mary.merge(Author.where(id: bob))
74
- end
60
+ assert_equal [bob], david_and_mary.merge(Author.where(id: bob))
75
61
  assert_equal [bob], david_and_mary.merge(Author.rewhere(id: bob))
76
- assert_equal [bob], david_and_mary.merge(Author.where(id: bob), rewhere: true)
77
62
 
78
- assert_deprecated(message) do
79
- assert_equal [bob], mary_and_bob.merge(Author.where(id: [david, bob]))
80
- end
81
- assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]), rewhere: true)
82
-
83
- message = %r/Merging \(#{author_id} BETWEEN (\?|\W?\w?\d) AND \g<1>\) and \(#{author_id} BETWEEN \g<1> AND \g<1>\) no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0\./
63
+ assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]))
84
64
 
85
- assert_deprecated(message) do
86
- assert_equal [mary], david_and_mary.merge(mary_and_bob)
87
- end
88
- assert_equal [mary, bob], david_and_mary.merge(mary_and_bob, rewhere: true)
65
+ assert_equal [mary, bob], david_and_mary.merge(mary_and_bob)
89
66
  assert_equal [mary], david_and_mary.and(mary_and_bob)
90
67
  assert_equal authors, david_and_mary.or(mary_and_bob)
91
68
 
92
- assert_deprecated(message) do
93
- assert_equal [mary], mary_and_bob.merge(david_and_mary)
94
- end
95
- assert_equal [david, mary], mary_and_bob.merge(david_and_mary, rewhere: true)
69
+ assert_equal [david, mary], mary_and_bob.merge(david_and_mary)
96
70
  assert_equal [mary], david_and_mary.and(mary_and_bob)
97
71
  assert_equal authors, david_and_mary.or(mary_and_bob)
98
72
 
99
73
  david_and_bob = Author.where(id: david).or(Author.where(name: "Bob"))
100
74
 
101
75
  assert_equal [david], david_and_mary.merge(david_and_bob)
102
- assert_equal [david], david_and_mary.merge(david_and_bob, rewhere: true)
103
76
  assert_equal [david], david_and_mary.and(david_and_bob)
104
77
  assert_equal authors, david_and_mary.or(david_and_bob)
105
78
  end
@@ -113,46 +86,26 @@ class RelationMergingTest < ActiveRecord::TestCase
113
86
  assert_equal [david, mary], david_and_mary
114
87
  assert_equal [mary, bob], mary_and_bob
115
88
 
116
- author_id = Regexp.escape(Author.connection.quote_table_name("authors.id"))
117
- message = %r/Merging \(\(#{author_id} = (\?|\W?\w?\d) OR #{author_id} = \g<1>\)\) and \(#{author_id} (?:= \g<1>|IN \(\g<1>, \g<1>\))\) no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0\./
118
-
119
- assert_deprecated(message) do
120
- assert_equal [mary], david_and_mary.merge(Author.where(id: mary))
121
- end
89
+ assert_equal [mary], david_and_mary.merge(Author.where(id: mary))
122
90
  assert_equal [mary], david_and_mary.merge(Author.rewhere(id: mary))
123
- assert_equal [mary], david_and_mary.merge(Author.where(id: mary), rewhere: true)
124
91
 
125
- assert_deprecated(message) do
126
- assert_equal [], david_and_mary.merge(Author.where(id: bob))
127
- end
92
+ assert_equal [bob], david_and_mary.merge(Author.where(id: bob))
128
93
  assert_equal [bob], david_and_mary.merge(Author.rewhere(id: bob))
129
- assert_equal [bob], david_and_mary.merge(Author.where(id: bob), rewhere: true)
130
94
 
131
- assert_deprecated(message) do
132
- assert_equal [bob], mary_and_bob.merge(Author.where(id: [david, bob]))
133
- end
134
- assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]), rewhere: true)
95
+ assert_equal [david, bob], mary_and_bob.merge(Author.where(id: [david, bob]))
135
96
 
136
- message = %r/Merging \(\(#{author_id} = (\?|\W?\w?\d) OR #{author_id} = \g<1>\)\) and \(\(#{author_id} = \g<1> OR #{author_id} = \g<1>\)\) no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0\./
137
97
 
138
- assert_deprecated(message) do
139
- assert_equal [mary], david_and_mary.merge(mary_and_bob)
140
- end
141
- assert_equal [mary, bob], david_and_mary.merge(mary_and_bob, rewhere: true)
98
+ assert_equal [mary, bob], david_and_mary.merge(mary_and_bob)
142
99
  assert_equal [mary], david_and_mary.and(mary_and_bob)
143
100
  assert_equal authors, david_and_mary.or(mary_and_bob)
144
101
 
145
- assert_deprecated(message) do
146
- assert_equal [mary], mary_and_bob.merge(david_and_mary)
147
- end
148
- assert_equal [david, mary], mary_and_bob.merge(david_and_mary, rewhere: true)
102
+ assert_equal [david, mary], mary_and_bob.merge(david_and_mary)
149
103
  assert_equal [mary], david_and_mary.and(mary_and_bob)
150
104
  assert_equal authors, david_and_mary.or(mary_and_bob)
151
105
 
152
106
  david_and_bob = Author.where(id: david).or(Author.where(name: "Bob"))
153
107
 
154
108
  assert_equal [david], david_and_mary.merge(david_and_bob)
155
- assert_equal [david], david_and_mary.merge(david_and_bob, rewhere: true)
156
109
  assert_equal [david], david_and_mary.and(david_and_bob)
157
110
  assert_equal authors, david_and_mary.or(david_and_bob)
158
111
  end
@@ -164,15 +117,9 @@ class RelationMergingTest < ActiveRecord::TestCase
164
117
 
165
118
  assert_equal [david], non_mary_and_bob
166
119
 
167
- assert_deprecated do
168
- assert_equal [david], Author.where(id: david).merge(non_mary_and_bob)
169
- end
170
- assert_equal [david], Author.where(id: david).merge(non_mary_and_bob, rewhere: true)
120
+ assert_equal [david], Author.where(id: david).merge(non_mary_and_bob)
171
121
 
172
- assert_deprecated do
173
- assert_equal [], Author.where(id: mary).merge(non_mary_and_bob)
174
- end
175
- assert_equal [david], Author.where(id: mary).merge(non_mary_and_bob, rewhere: true)
122
+ assert_equal [david], Author.where(id: mary).merge(non_mary_and_bob)
176
123
  end
177
124
 
178
125
  def test_merge_not_range_clause
@@ -182,15 +129,9 @@ class RelationMergingTest < ActiveRecord::TestCase
182
129
 
183
130
  assert_equal [david, mary], less_than_bob
184
131
 
185
- assert_deprecated do
186
- assert_equal [david], Author.where(id: david).merge(less_than_bob)
187
- end
188
- assert_equal [david, mary], Author.where(id: david).merge(less_than_bob, rewhere: true)
132
+ assert_equal [david, mary], Author.where(id: david).merge(less_than_bob)
189
133
 
190
- assert_deprecated do
191
- assert_equal [mary], Author.where(id: mary).merge(less_than_bob)
192
- end
193
- assert_equal [david, mary], Author.where(id: mary).merge(less_than_bob, rewhere: true)
134
+ assert_equal [david, mary], Author.where(id: mary).merge(less_than_bob)
194
135
  end
195
136
 
196
137
  def test_merge_doesnt_duplicate_same_clauses
@@ -198,19 +139,27 @@ class RelationMergingTest < ActiveRecord::TestCase
198
139
 
199
140
  non_mary_and_bob = Author.where.not(id: [mary, bob])
200
141
 
201
- author_id = Author.connection.quote_table_name("authors.id")
202
- assert_sql(/WHERE #{Regexp.escape(author_id)} NOT IN \((\?|\W?\w?\d), \g<1>\)\z/) do
142
+ author_id = quote_table_name("authors.id")
143
+ assert_queries_match(/WHERE #{Regexp.escape(author_id)} NOT IN \((\?|\W?\w?\d), \g<1>\)\z/) do
203
144
  assert_equal [david], non_mary_and_bob.merge(non_mary_and_bob)
204
145
  end
205
146
 
206
147
  only_david = Author.where("#{author_id} IN (?)", david)
207
148
 
208
- assert_sql(/WHERE \(#{Regexp.escape(author_id)} IN \(1\)\)\z/) do
209
- assert_equal [david], only_david.merge(only_david)
149
+ matcher = if Author.lease_connection.prepared_statements
150
+ if current_adapter?(:PostgreSQLAdapter)
151
+ /WHERE \(#{Regexp.escape(author_id)} IN \(\$1\)\)\z/
152
+ else
153
+ /WHERE \(#{Regexp.escape(author_id)} IN \(\?\)\)\z/
154
+ end
155
+ elsif current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
156
+ /WHERE \(#{Regexp.escape(author_id)} IN \('1'\)\)\z/
157
+ else
158
+ /WHERE \(#{Regexp.escape(author_id)} IN \(1\)\)\z/
210
159
  end
211
160
 
212
- assert_sql(/WHERE \(#{Regexp.escape(author_id)} IN \(1\)\)\z/) do
213
- assert_equal [david], only_david.merge(only_david, rewhere: true)
161
+ assert_queries_match(matcher) do
162
+ assert_equal [david], only_david.merge(only_david)
214
163
  end
215
164
  end
216
165
 
@@ -234,9 +183,6 @@ class RelationMergingTest < ActiveRecord::TestCase
234
183
  devs = Developer.where(salary_attr.eq(80000)).merge(Developer.where(salary_attr.eq(9000)))
235
184
  assert_equal [developers(:poor_jamis)], devs.to_a
236
185
 
237
- devs = Developer.where(salary_attr.eq(80000)).merge(Developer.where(salary_attr.eq(9000)), rewhere: true)
238
- assert_equal [developers(:poor_jamis)], devs.to_a
239
-
240
186
  devs = Developer.where(salary_attr.eq(80000)).rewhere(salary_attr.eq(9000))
241
187
  assert_equal [developers(:poor_jamis)], devs.to_a
242
188
  end
@@ -248,9 +194,6 @@ class RelationMergingTest < ActiveRecord::TestCase
248
194
  devs = Developer.where(abs_salary.eq(80000)).merge(Developer.where(abs_salary.eq(9000)))
249
195
  assert_equal [developers(:poor_jamis)], devs.to_a
250
196
 
251
- devs = Developer.where(abs_salary.eq(80000)).merge(Developer.where(abs_salary.eq(9000)), rewhere: true)
252
- assert_equal [developers(:poor_jamis)], devs.to_a
253
-
254
197
  devs = Developer.where(abs_salary.eq(80000)).rewhere(abs_salary.eq(9000))
255
198
  assert_equal [developers(:poor_jamis)], devs.to_a
256
199
  end
@@ -273,7 +216,7 @@ class RelationMergingTest < ActiveRecord::TestCase
273
216
 
274
217
  def test_relation_merging_with_preload
275
218
  [Post.all.merge(Post.preload(:author)), Post.preload(:author).merge(Post.all)].each do |posts|
276
- assert_queries(2) { assert posts.first.author }
219
+ assert_queries_count(2) { assert posts.first.author }
277
220
  end
278
221
  end
279
222
 
@@ -289,11 +232,11 @@ class RelationMergingTest < ActiveRecord::TestCase
289
232
  end
290
233
 
291
234
  def test_relation_merging_with_skip_query_cache
292
- assert_equal Post.all.merge(Post.all.skip_query_cache!).skip_query_cache_value, true
235
+ assert_equal true, Post.all.merge(Post.all.skip_query_cache!).skip_query_cache_value
293
236
  end
294
237
 
295
238
  def test_relation_merging_with_association
296
- assert_queries(2) do # one for loading post, and another one merged query
239
+ assert_queries_count(2) do # one for loading post, and another one merged query
297
240
  post = Post.where(body: "Such a lovely day").first
298
241
  comments = Comment.where(body: "Thank you for the welcome").merge(post.comments)
299
242
  assert_equal 1, comments.count
@@ -347,42 +290,31 @@ class RelationMergingTest < ActiveRecord::TestCase
347
290
  end
348
291
 
349
292
  def test_merging_annotations_respects_merge_order
350
- assert_sql(%r{/\* foo \*/ /\* bar \*/}) do
293
+ assert_queries_match(%r{/\* foo \*/ /\* bar \*/}) do
351
294
  Post.annotate("foo").merge(Post.annotate("bar")).first
352
295
  end
353
- assert_sql(%r{/\* bar \*/ /\* foo \*/}) do
296
+ assert_queries_match(%r{/\* bar \*/ /\* foo \*/}) do
354
297
  Post.annotate("bar").merge(Post.annotate("foo")).first
355
298
  end
356
- assert_sql(%r{/\* foo \*/ /\* bar \*/ /\* baz \*/ /\* qux \*/}) do
299
+ assert_queries_match(%r{/\* foo \*/ /\* bar \*/ /\* baz \*/ /\* qux \*/}) do
357
300
  Post.annotate("foo").annotate("bar").merge(Post.annotate("baz").annotate("qux")).first
358
301
  end
359
302
  end
360
303
 
361
304
  def test_merging_duplicated_annotations
362
305
  posts = Post.annotate("foo")
363
- assert_sql(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/\z}) do
306
+ assert_queries_match(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/\z}) do
364
307
  posts.merge(posts).uniq!(:annotate).to_a
365
308
  end
366
309
 
367
- message = <<-MSG.squish
368
- Duplicated query annotations are no longer shown in queries in Rails 7.0.
369
- To migrate to Rails 7.0's behavior, use `uniq!(:annotate)` to deduplicate query annotations
370
- (`posts.uniq!(:annotate)`).
371
- MSG
372
- assert_deprecated(message) do
373
- assert_sql(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/ /\* foo \*/\z}) do
374
- posts.merge(posts).to_a
375
- end
310
+ assert_queries_match(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/\z}) do
311
+ posts.merge(posts).to_a
376
312
  end
377
- assert_deprecated(message) do
378
- assert_sql(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/ /\* bar \*/ /\* foo \*/\z}) do
379
- Post.annotate("foo").merge(Post.annotate("bar")).merge(posts).to_a
380
- end
313
+ assert_queries_match(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* foo \*/ /\* bar \*/\z}) do
314
+ Post.annotate("foo").merge(Post.annotate("bar")).merge(posts).to_a
381
315
  end
382
- assert_deprecated(message) do
383
- assert_sql(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* bar \*/ /\* foo \*/ /\* foo \*/\z}) do
384
- Post.annotate("bar").merge(Post.annotate("foo")).merge(posts).to_a
385
- end
316
+ assert_queries_match(%r{FROM #{Regexp.escape(Post.quoted_table_name)} /\* bar \*/ /\* foo \*/\z}) do
317
+ Post.annotate("bar").merge(Post.annotate("foo")).merge(posts).to_a
386
318
  end
387
319
  end
388
320
  end
@@ -431,4 +363,43 @@ class MergingDifferentRelationsTest < ActiveRecord::TestCase
431
363
 
432
364
  assert_equal dev.ratings, [rating_1]
433
365
  end
366
+
367
+ test "merging where relation having arel equality with null relation" do
368
+ skip "DB2 emits SQL literal predicates for this NULL equality shape, which ActiveRecord relation merge cannot de-duplicate" if current_adapter?(:IBM_DBAdapter)
369
+
370
+ arel_predicate = Arel::Nodes::NamedFunction.new("ABS", [Post.arel_table[:tags_count]]).eq(0)
371
+ arel_relation = Post.where(arel_predicate)
372
+ relation = arel_relation.merge(arel_relation.none)
373
+ sql = relation.to_sql
374
+ assert_match("AND", sql)
375
+ end
376
+
377
+ if ActiveRecord::Base.lease_connection.supports_common_table_expressions?
378
+ test "merging relation with common table expression" do
379
+ posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0")).from("posts_with_tags AS posts")
380
+ posts_with_comments = Post.where("legacy_comments_count > 0")
381
+ relation = posts_with_comments.merge(posts_with_tags).order("posts.id")
382
+
383
+ assert_equal [1, 2, 7], relation.pluck(:id)
384
+ end
385
+
386
+ test "merging multiple relations with common table expression" do
387
+ posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0"))
388
+ posts_with_comments = Post.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
389
+ relation = posts_with_comments.merge(posts_with_tags)
390
+ .joins("JOIN posts_with_tags pwt ON pwt.id = posts.id JOIN posts_with_comments pwc ON pwc.id = posts.id").order("posts.id")
391
+
392
+ assert_equal [1, 2, 7], relation.pluck(:id)
393
+ end
394
+
395
+ test "relation merger leaves to database to decide what to do when multiple CTEs with same alias are passed" do
396
+ posts_with_tags = Post.with(popular_posts: Post.where("tags_count > 0"))
397
+ posts_with_comments = Post.with(popular_posts: Post.where("legacy_comments_count > 0"))
398
+ relation = posts_with_tags.merge(posts_with_comments).joins("JOIN popular_posts pp ON pp.id = posts.id")
399
+
400
+ assert_raises ActiveRecord::StatementInvalid do
401
+ relation.load
402
+ end
403
+ end
404
+ end
434
405
  end
@@ -5,7 +5,7 @@ require "models/post"
5
5
 
6
6
  module ActiveRecord
7
7
  class RelationMutationTest < ActiveRecord::TestCase
8
- (Relation::MULTI_VALUE_METHODS - [:extending, :order, :unscope, :select]).each do |method|
8
+ (Relation::MULTI_VALUE_METHODS - [:extending, :order, :unscope, :select, :with]).each do |method|
9
9
  test "##{method}!" do
10
10
  assert relation.public_send("#{method}!", :foo).equal?(relation)
11
11
  assert_equal [:foo], relation.public_send("#{method}_values")
@@ -32,10 +32,8 @@ module ActiveRecord
32
32
 
33
33
  test "#order! on non-string does not attempt regexp match for references" do
34
34
  obj = Object.new
35
- assert_not_called(obj, :=~) do
36
- assert relation.order!(obj)
37
- assert_equal [obj], relation.order_values
38
- end
35
+ assert relation.order!(obj)
36
+ assert_equal [obj], relation.order_values
39
37
  end
40
38
 
41
39
  test "extending!" do
@@ -118,8 +116,8 @@ module ActiveRecord
118
116
 
119
117
  test "none!" do
120
118
  assert relation.none!.equal?(relation)
121
- assert_equal [NullRelation], relation.extending_values
122
- assert relation.is_a?(NullRelation)
119
+ assert_predicate relation, :none?
120
+ assert_predicate relation, :null_relation?
123
121
  end
124
122
 
125
123
  test "distinct!" do
@@ -137,6 +135,13 @@ module ActiveRecord
137
135
  assert relation.skip_preloading_value
138
136
  end
139
137
 
138
+ test "#regroup!" do
139
+ @relation = relation.group("foo")
140
+
141
+ assert relation.regroup!("bar").equal?(relation)
142
+ assert_equal ["bar"], relation.group_values
143
+ end
144
+
140
145
  private
141
146
  def relation
142
147
  @relation ||= Relation.new(FakeKlass)
@@ -4,7 +4,8 @@ require "cases/helper"
4
4
  require "models/author"
5
5
  require "models/categorization"
6
6
  require "models/post"
7
- require "models/citation"
7
+ require "models/book"
8
+ require "models/paragraph"
8
9
 
9
10
  module ActiveRecord
10
11
  class OrTest < ActiveRecord::TestCase
@@ -133,9 +134,11 @@ module ActiveRecord
133
134
  end
134
135
 
135
136
  def test_or_with_non_relation_object_raises_error
136
- assert_raises ArgumentError do
137
+ error = assert_raises ArgumentError do
137
138
  Post.where(id: [1, 2, 3]).or(title: "Rails")
138
139
  end
140
+
141
+ assert_equal "You have passed Hash object to #or. Pass an ActiveRecord::Relation object instead.", error.message
139
142
  end
140
143
 
141
144
  def test_or_with_references_inequality
@@ -176,16 +179,16 @@ module ActiveRecord
176
179
 
177
180
  # The maximum expression tree depth is 1000 by default for SQLite3.
178
181
  # https://www.sqlite.org/limits.html#max_expr_depth
179
- unless current_adapter?(:SQLite3Adapter)
180
- class TooManyOrTest < ActiveRecord::TestCase
181
- fixtures :citations
182
+ class TooManyOrTest < ActiveRecord::TestCase
183
+ unless current_adapter?(:SQLite3Adapter)
184
+ fixtures :paragraphs
182
185
 
183
186
  def test_too_many_or
184
- citations = 6000.times.map do |i|
185
- Citation.where(id: i, book2_id: i * i)
187
+ paragraphs = 1001.times.map do |i|
188
+ Paragraph.where(id: i, book_id: i * i)
186
189
  end
187
190
 
188
- assert_equal 6000, citations.inject(&:or).count
191
+ assert_equal 1001, paragraphs.inject(&:or).count
189
192
  end
190
193
  end
191
194
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+ require "models/book"
6
+
7
+ class OrderTest < ActiveRecord::TestCase
8
+ fixtures :authors, :author_addresses
9
+
10
+ def setup
11
+ Book.delete_all
12
+ end
13
+
14
+ def test_order_asc
15
+ z = Book.create!(name: "Zulu", author: authors(:david))
16
+ y = Book.create!(name: "Yankee", author: authors(:mary))
17
+ x = Book.create!(name: "X-Ray", author: authors(:david))
18
+
19
+ alphabetical = [x, y, z]
20
+
21
+ assert_equal(alphabetical, Book.order(name: :asc))
22
+ assert_equal(alphabetical, Book.order(name: :ASC))
23
+ assert_equal(alphabetical, Book.order(name: "asc"))
24
+ assert_equal(alphabetical, Book.order(:name))
25
+ assert_equal(alphabetical, Book.order("name"))
26
+ assert_equal(alphabetical, Book.order("books.name"))
27
+ assert_equal(alphabetical, Book.order(Book.arel_table["name"]))
28
+ assert_equal(alphabetical, Book.order(books: { name: :asc }))
29
+ end
30
+
31
+ def test_order_desc
32
+ z = Book.create!(name: "Zulu", author: authors(:david))
33
+ y = Book.create!(name: "Yankee", author: authors(:mary))
34
+ x = Book.create!(name: "X-Ray", author: authors(:david))
35
+
36
+ reverse_alphabetical = [z, y, x]
37
+
38
+ assert_equal(reverse_alphabetical, Book.order(name: :desc))
39
+ assert_equal(reverse_alphabetical, Book.order(name: :DESC))
40
+ assert_equal(reverse_alphabetical, Book.order(name: "desc"))
41
+ assert_equal(reverse_alphabetical, Book.order(:name).reverse_order)
42
+ assert_equal(reverse_alphabetical, Book.order("name desc"))
43
+ assert_equal(reverse_alphabetical, Book.order("books.name desc"))
44
+ assert_equal(reverse_alphabetical, Book.order(Book.arel_table["name"].desc))
45
+ assert_equal(reverse_alphabetical, Book.order(books: { name: :desc }))
46
+ end
47
+
48
+ def test_order_with_association
49
+ z = Book.create!(name: "Zulu", author: authors(:david))
50
+ y = Book.create!(name: "Yankee", author: authors(:mary))
51
+ x = Book.create!(name: "X-Ray", author: authors(:david))
52
+
53
+ author_then_book_name = [x, z, y]
54
+
55
+ assert_equal(author_then_book_name, Book.includes(:author).order(authors: { name: :asc }, books: { name: :asc }))
56
+ assert_equal(author_then_book_name, Book.includes(:author).order("authors.name", books: { name: :asc }))
57
+ assert_equal(author_then_book_name, Book.includes(:author).order("authors.name", "books.name"))
58
+ assert_equal(author_then_book_name, Book.includes(:author).order({ authors: { name: :asc } }, Book.arel_table[:name]))
59
+ assert_equal(author_then_book_name, Book.includes(:author).order(Author.arel_table[:name], Book.arel_table[:name]))
60
+
61
+ author_desc_then_book_name = [y, x, z]
62
+
63
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order(authors: { name: :desc }, books: { name: :asc }))
64
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order("authors.name desc", books: { name: :asc }))
65
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order(Author.arel_table[:name].desc, books: { name: :asc }))
66
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order({ authors: { name: :desc } }, :name))
67
+ end
68
+
69
+ def test_order_with_association_alias
70
+ z = Book.create!(name: "Zulu", author: authors(:david))
71
+ y = Book.create!(name: "Yankee", author: authors(:mary))
72
+ x = Book.create!(name: "X-Ray", author: authors(:david))
73
+
74
+ author_name = Author.arel_table.alias("author")[:name]
75
+
76
+ author_then_book_name = [x, z, y]
77
+
78
+ assert_equal(author_then_book_name, Book.includes(:author).order(author: { name: :asc }, books: { name: :asc }))
79
+ assert_equal(author_then_book_name, Book.includes(:author).order("author.name", books: { name: :asc }))
80
+ assert_equal(author_then_book_name, Book.includes(:author).order({ author: { name: :asc } }, :name))
81
+ assert_equal(author_then_book_name, Book.includes(:author).order(author_name, :name))
82
+
83
+ author_desc_then_book_name = [y, x, z]
84
+
85
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order(author: { name: :desc }, books: { name: :asc }))
86
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order("author.name desc", books: { name: :asc }))
87
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order({ author: { name: :desc } }, :name))
88
+ assert_equal(author_desc_then_book_name, Book.includes(:author).order(author_name.desc, :name))
89
+ end
90
+ end
@@ -16,16 +16,31 @@ module ActiveRecord
16
16
  end
17
17
 
18
18
  def test_registering_new_handlers
19
- assert_match %r{#{Regexp.escape(topic_title)} ~ 'rails'}i, Topic.where(title: /rails/).to_sql
19
+ assert_match %r{#{Regexp.escape(quote_table_name("topics.title"))} ~ 'rails'}i, Topic.where(title: /rails/).to_sql
20
20
  end
21
21
 
22
22
  def test_registering_new_handlers_for_association
23
- assert_match %r{#{Regexp.escape(topic_title)} ~ 'rails'}i, Reply.joins(:topic).where(topics: { title: /rails/ }).to_sql
23
+ assert_match %r{#{Regexp.escape(quote_table_name("topics.title"))} ~ 'rails'}i, Reply.joins(:topic).where(topics: { title: /rails/ }).to_sql
24
24
  end
25
25
 
26
- private
27
- def topic_title
28
- Topic.connection.quote_table_name("topics.title")
29
- end
26
+ def test_registering_new_handlers_for_joins
27
+ Reply.belongs_to :regexp_topic, -> { where(title: /rails/) }, class_name: "Topic", foreign_key: "parent_id"
28
+
29
+ assert_match %r{#{Regexp.escape(quote_table_name("regexp_topic.title"))} ~ 'rails'}i, Reply.joins(:regexp_topic).references(Arel.sql("regexp_topic")).to_sql
30
+ end
31
+
32
+ def test_references_with_schema
33
+ assert_equal %w{schema.table}, ActiveRecord::PredicateBuilder.references(%w{schema.table.column})
34
+ end
35
+
36
+ def test_build_from_hash_with_schema
37
+ assert_match %r{schema.+table.+column}i, Topic.predicate_builder.build_from_hash("schema.table.column" => "value").first.to_sql
38
+ end
39
+
40
+ def test_does_not_mutate
41
+ defaults = { topics: { title: "rails" }, "topics.approved" => true }
42
+ Topic.where(defaults).to_sql
43
+ assert_equal({ topics: { title: "rails" }, "topics.approved" => true }, defaults)
44
+ end
30
45
  end
31
46
  end