ibm_db 3.0.5-x86-mingw32 → 5.0.5-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +4 -0
  3. data/LICENSE +1 -1
  4. data/ParameterizedQueries README +6 -6
  5. data/README +38 -55
  6. data/ext/Makefile +269 -0
  7. data/ext/extconf.rb +34 -3
  8. data/ext/gil_release_version +3 -0
  9. data/ext/ibm_db-i386-mingw32.def +2 -0
  10. data/ext/ibm_db.c +100 -108
  11. data/ext/ibm_db.o +0 -0
  12. data/ext/ibm_db.so +0 -0
  13. data/ext/mkmf.log +110 -0
  14. data/ext/ruby_ibm_db_cli.o +0 -0
  15. data/ext/unicode_support_version +3 -0
  16. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +923 -527
  17. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +4 -1
  18. data/lib/mswin32/ibm_db.rb +7 -39
  19. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  20. data/test/active_record/connection_adapters/fake_adapter.rb +8 -5
  21. data/test/cases/adapter_test.rb +133 -58
  22. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  23. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  24. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  25. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  26. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  27. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  28. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  29. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  30. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  31. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  32. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  33. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  34. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  35. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  36. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  37. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  38. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  39. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  40. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  41. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  42. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  43. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  44. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  45. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  46. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  47. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  48. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  49. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  50. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  51. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  52. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  53. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  54. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  55. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  56. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  57. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  58. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  59. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  60. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  61. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  62. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  63. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  64. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  65. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  66. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  67. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  68. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  69. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  70. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  71. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  72. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  73. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  74. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  75. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  76. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  77. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  78. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  79. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  80. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  81. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  82. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  83. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  84. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  85. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  86. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  87. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  88. data/test/cases/aggregations_test.rb +11 -1
  89. data/test/cases/ar_schema_test.rb +35 -50
  90. data/test/cases/associations/association_scope_test.rb +1 -6
  91. data/test/cases/associations/belongs_to_associations_test.rb +122 -10
  92. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  93. data/test/cases/associations/callbacks_test.rb +5 -7
  94. data/test/cases/associations/cascaded_eager_loading_test.rb +1 -1
  95. data/test/cases/associations/eager_load_nested_include_test.rb +1 -3
  96. data/test/cases/associations/eager_test.rb +158 -73
  97. data/test/cases/associations/extension_test.rb +7 -2
  98. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +64 -32
  99. data/test/cases/associations/has_many_associations_test.rb +362 -43
  100. data/test/cases/associations/has_many_through_associations_test.rb +108 -41
  101. data/test/cases/associations/has_one_associations_test.rb +105 -8
  102. data/test/cases/associations/has_one_through_associations_test.rb +6 -3
  103. data/test/cases/associations/inner_join_association_test.rb +3 -3
  104. data/test/cases/associations/inverse_associations_test.rb +38 -11
  105. data/test/cases/associations/join_model_test.rb +59 -36
  106. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  107. data/test/cases/associations/nested_through_associations_test.rb +2 -2
  108. data/test/cases/associations/required_test.rb +25 -5
  109. data/test/cases/associations_test.rb +39 -34
  110. data/test/cases/attribute_decorators_test.rb +9 -8
  111. data/test/cases/attribute_methods/read_test.rb +5 -5
  112. data/test/cases/attribute_methods_test.rb +97 -40
  113. data/test/cases/attribute_set_test.rb +64 -4
  114. data/test/cases/attribute_test.rb +84 -18
  115. data/test/cases/attributes_test.rb +151 -34
  116. data/test/cases/autosave_association_test.rb +149 -36
  117. data/test/cases/base_test.rb +290 -241
  118. data/test/cases/batches_test.rb +299 -22
  119. data/test/cases/binary_test.rb +2 -10
  120. data/test/cases/bind_parameter_test.rb +76 -66
  121. data/test/cases/cache_key_test.rb +26 -0
  122. data/test/cases/calculations_test.rb +167 -15
  123. data/test/cases/callbacks_test.rb +161 -68
  124. data/test/cases/coders/json_test.rb +15 -0
  125. data/test/cases/collection_cache_key_test.rb +115 -0
  126. data/test/cases/column_definition_test.rb +26 -57
  127. data/test/cases/comment_test.rb +145 -0
  128. data/test/cases/connection_adapters/adapter_leasing_test.rb +5 -3
  129. data/test/cases/connection_adapters/connection_handler_test.rb +128 -21
  130. data/test/cases/connection_adapters/connection_specification_test.rb +1 -1
  131. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +0 -38
  132. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -1
  133. data/test/cases/connection_adapters/schema_cache_test.rb +8 -3
  134. data/test/cases/connection_adapters/type_lookup_test.rb +15 -7
  135. data/test/cases/connection_management_test.rb +46 -56
  136. data/test/cases/connection_pool_test.rb +195 -20
  137. data/test/cases/connection_specification/resolver_test.rb +15 -0
  138. data/test/cases/counter_cache_test.rb +10 -5
  139. data/test/cases/custom_locking_test.rb +1 -1
  140. data/test/cases/database_statements_test.rb +18 -3
  141. data/test/cases/{invalid_date_test.rb → date_test.rb} +13 -1
  142. data/test/cases/date_time_precision_test.rb +107 -0
  143. data/test/cases/defaults_test.rb +85 -89
  144. data/test/cases/dirty_test.rb +30 -52
  145. data/test/cases/disconnected_test.rb +4 -2
  146. data/test/cases/enum_test.rb +178 -24
  147. data/test/cases/errors_test.rb +16 -0
  148. data/test/cases/explain_test.rb +32 -21
  149. data/test/cases/finder_test.rb +273 -148
  150. data/test/cases/fixture_set/file_test.rb +18 -0
  151. data/test/cases/fixtures_test.rb +112 -32
  152. data/test/cases/forbidden_attributes_protection_test.rb +69 -3
  153. data/test/cases/helper.rb +10 -16
  154. data/test/cases/hot_compatibility_test.rb +89 -1
  155. data/test/cases/inheritance_test.rb +284 -53
  156. data/test/cases/integration_test.rb +23 -7
  157. data/test/cases/invalid_connection_test.rb +4 -2
  158. data/test/cases/invertible_migration_test.rb +124 -32
  159. data/test/cases/json_serialization_test.rb +11 -2
  160. data/test/cases/locking_test.rb +22 -6
  161. data/test/cases/log_subscriber_test.rb +106 -17
  162. data/test/cases/migration/change_schema_test.rb +60 -114
  163. data/test/cases/migration/change_table_test.rb +34 -2
  164. data/test/cases/migration/column_attributes_test.rb +7 -23
  165. data/test/cases/migration/column_positioning_test.rb +8 -8
  166. data/test/cases/migration/columns_test.rb +17 -11
  167. data/test/cases/migration/command_recorder_test.rb +47 -2
  168. data/test/cases/migration/compatibility_test.rb +118 -0
  169. data/test/cases/migration/create_join_table_test.rb +21 -12
  170. data/test/cases/migration/foreign_key_test.rb +52 -18
  171. data/test/cases/migration/index_test.rb +14 -12
  172. data/test/cases/migration/logger_test.rb +1 -1
  173. data/test/cases/migration/pending_migrations_test.rb +0 -1
  174. data/test/cases/migration/references_foreign_key_test.rb +59 -7
  175. data/test/cases/migration/references_index_test.rb +4 -4
  176. data/test/cases/migration/references_statements_test.rb +26 -6
  177. data/test/cases/migration/rename_table_test.rb +25 -25
  178. data/test/cases/migration_test.rb +279 -81
  179. data/test/cases/migrator_test.rb +91 -8
  180. data/test/cases/mixin_test.rb +0 -2
  181. data/test/cases/modules_test.rb +3 -4
  182. data/test/cases/multiparameter_attributes_test.rb +24 -2
  183. data/test/cases/multiple_db_test.rb +11 -4
  184. data/test/cases/nested_attributes_test.rb +61 -33
  185. data/test/cases/persistence_test.rb +102 -10
  186. data/test/cases/pooled_connections_test.rb +3 -3
  187. data/test/cases/primary_keys_test.rb +170 -31
  188. data/test/cases/query_cache_test.rb +216 -96
  189. data/test/cases/quoting_test.rb +65 -19
  190. data/test/cases/readonly_test.rb +2 -1
  191. data/test/cases/reflection_test.rb +68 -22
  192. data/test/cases/relation/delegation_test.rb +3 -8
  193. data/test/cases/relation/merging_test.rb +10 -14
  194. data/test/cases/relation/mutation_test.rb +42 -24
  195. data/test/cases/relation/or_test.rb +92 -0
  196. data/test/cases/relation/predicate_builder_test.rb +4 -2
  197. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  198. data/test/cases/relation/where_chain_test.rb +23 -99
  199. data/test/cases/relation/where_clause_test.rb +182 -0
  200. data/test/cases/relation/where_test.rb +45 -23
  201. data/test/cases/relation_test.rb +67 -58
  202. data/test/cases/relations_test.rb +249 -38
  203. data/test/cases/result_test.rb +10 -0
  204. data/test/cases/sanitize_test.rb +108 -15
  205. data/test/cases/schema_dumper_test.rb +119 -125
  206. data/test/cases/schema_loading_test.rb +52 -0
  207. data/test/cases/scoping/default_scoping_test.rb +113 -39
  208. data/test/cases/scoping/named_scoping_test.rb +46 -9
  209. data/test/cases/scoping/relation_scoping_test.rb +47 -4
  210. data/test/cases/secure_token_test.rb +32 -0
  211. data/test/cases/serialization_test.rb +1 -1
  212. data/test/cases/serialized_attribute_test.rb +93 -6
  213. data/test/cases/statement_cache_test.rb +38 -0
  214. data/test/cases/store_test.rb +2 -1
  215. data/test/cases/suppressor_test.rb +63 -0
  216. data/test/cases/tasks/database_tasks_test.rb +73 -9
  217. data/test/cases/tasks/mysql_rake_test.rb +139 -118
  218. data/test/cases/tasks/postgresql_rake_test.rb +60 -6
  219. data/test/cases/tasks/sqlite_rake_test.rb +30 -3
  220. data/test/cases/test_case.rb +28 -20
  221. data/test/cases/test_fixtures_test.rb +36 -0
  222. data/test/cases/time_precision_test.rb +103 -0
  223. data/test/cases/timestamp_test.rb +44 -10
  224. data/test/cases/touch_later_test.rb +121 -0
  225. data/test/cases/transaction_callbacks_test.rb +128 -62
  226. data/test/cases/transaction_isolation_test.rb +2 -2
  227. data/test/cases/transactions_test.rb +61 -43
  228. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  229. data/test/cases/type/date_time_test.rb +14 -0
  230. data/test/cases/type/integer_test.rb +2 -96
  231. data/test/cases/type/string_test.rb +0 -14
  232. data/test/cases/type_test.rb +39 -0
  233. data/test/cases/types_test.rb +1 -118
  234. data/test/cases/unconnected_test.rb +1 -1
  235. data/test/cases/validations/absence_validation_test.rb +73 -0
  236. data/test/cases/validations/association_validation_test.rb +13 -2
  237. data/test/cases/validations/i18n_validation_test.rb +6 -10
  238. data/test/cases/validations/length_validation_test.rb +62 -30
  239. data/test/cases/validations/presence_validation_test.rb +36 -1
  240. data/test/cases/validations/uniqueness_validation_test.rb +128 -37
  241. data/test/cases/validations_repair_helper.rb +2 -6
  242. data/test/cases/validations_test.rb +36 -7
  243. data/test/cases/view_test.rb +102 -5
  244. data/test/cases/yaml_serialization_test.rb +21 -26
  245. data/test/config.example.yml +97 -0
  246. data/test/fixtures/bad_posts.yml +9 -0
  247. data/test/fixtures/books.yml +20 -0
  248. data/test/fixtures/content.yml +3 -0
  249. data/test/fixtures/content_positions.yml +3 -0
  250. data/test/fixtures/dead_parrots.yml +5 -0
  251. data/test/fixtures/live_parrots.yml +4 -0
  252. data/test/fixtures/naked/yml/parrots.yml +2 -0
  253. data/test/fixtures/naked/yml/trees.yml +3 -0
  254. data/test/fixtures/nodes.yml +29 -0
  255. data/test/fixtures/other_comments.yml +6 -0
  256. data/test/fixtures/other_dogs.yml +2 -0
  257. data/test/fixtures/other_posts.yml +7 -0
  258. data/test/fixtures/price_estimates.yml +10 -1
  259. data/test/fixtures/trees.yml +3 -0
  260. data/test/migrations/10_urban/9_add_expressions.rb +1 -1
  261. data/test/migrations/decimal/1_give_me_big_numbers.rb +1 -1
  262. data/test/migrations/magic/1_currencies_have_symbols.rb +1 -1
  263. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -2
  264. data/test/migrations/missing/1_people_have_last_names.rb +2 -2
  265. data/test/migrations/missing/3_we_need_reminders.rb +2 -2
  266. data/test/migrations/missing/4_innocent_jointable.rb +2 -2
  267. data/test/migrations/rename/1_we_need_things.rb +2 -2
  268. data/test/migrations/rename/2_rename_things.rb +2 -2
  269. data/test/migrations/to_copy/1_people_have_hobbies.rb +1 -1
  270. data/test/migrations/to_copy/2_people_have_descriptions.rb +1 -1
  271. data/test/migrations/to_copy2/1_create_articles.rb +1 -1
  272. data/test/migrations/to_copy2/2_create_comments.rb +1 -1
  273. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +1 -1
  274. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +1 -1
  275. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +1 -1
  276. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +1 -1
  277. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +1 -1
  278. data/test/migrations/valid/1_valid_people_have_last_names.rb +1 -1
  279. data/test/migrations/valid/2_we_need_reminders.rb +2 -2
  280. data/test/migrations/valid/3_innocent_jointable.rb +2 -2
  281. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +1 -1
  282. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -2
  283. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +2 -2
  284. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +1 -1
  285. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +1 -1
  286. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +1 -1
  287. data/test/migrations/version_check/20131219224947_migration_version_check.rb +1 -1
  288. data/test/models/admin/randomly_named_c1.rb +6 -2
  289. data/test/models/aircraft.rb +1 -0
  290. data/test/models/author.rb +4 -7
  291. data/test/models/bird.rb +1 -1
  292. data/test/models/book.rb +5 -0
  293. data/test/models/bulb.rb +2 -1
  294. data/test/models/car.rb +3 -0
  295. data/test/models/cat.rb +10 -0
  296. data/test/models/chef.rb +1 -0
  297. data/test/models/club.rb +2 -0
  298. data/test/models/comment.rb +17 -5
  299. data/test/models/company.rb +4 -2
  300. data/test/models/company_in_module.rb +1 -1
  301. data/test/models/contact.rb +1 -1
  302. data/test/models/content.rb +40 -0
  303. data/test/models/customer.rb +8 -2
  304. data/test/models/developer.rb +19 -0
  305. data/test/models/face.rb +1 -1
  306. data/test/models/guitar.rb +4 -0
  307. data/test/models/hotel.rb +2 -0
  308. data/test/models/member.rb +1 -0
  309. data/test/models/member_detail.rb +4 -3
  310. data/test/models/mentor.rb +3 -0
  311. data/test/models/mocktail_designer.rb +2 -0
  312. data/test/models/node.rb +5 -0
  313. data/test/models/non_primary_key.rb +2 -0
  314. data/test/models/notification.rb +3 -0
  315. data/test/models/other_dog.rb +5 -0
  316. data/test/models/owner.rb +4 -1
  317. data/test/models/parrot.rb +6 -7
  318. data/test/models/person.rb +0 -1
  319. data/test/models/pet.rb +3 -0
  320. data/test/models/pet_treasure.rb +6 -0
  321. data/test/models/pirate.rb +3 -3
  322. data/test/models/post.rb +18 -9
  323. data/test/models/project.rb +9 -0
  324. data/test/models/randomly_named_c1.rb +1 -1
  325. data/test/models/recipe.rb +3 -0
  326. data/test/models/ship.rb +8 -2
  327. data/test/models/tag.rb +6 -0
  328. data/test/models/topic.rb +2 -8
  329. data/test/models/tree.rb +3 -0
  330. data/test/models/tuning_peg.rb +4 -0
  331. data/test/models/user.rb +14 -0
  332. data/test/models/uuid_item.rb +6 -0
  333. data/test/schema/mysql2_specific_schema.rb +33 -23
  334. data/test/schema/oracle_specific_schema.rb +1 -4
  335. data/test/schema/postgresql_specific_schema.rb +36 -124
  336. data/test/schema/schema.rb +170 -65
  337. data/test/schema/schema.rb.original +1057 -0
  338. data/test/schema/sqlite_specific_schema.rb +1 -5
  339. data/test/support/connection.rb +1 -0
  340. data/test/support/schema_dumping_helper.rb +1 -1
  341. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  342. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  343. metadata +146 -30
  344. data/lib/mswin32/rb19x/ibm_db.so +0 -0
  345. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  346. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  347. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  348. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  349. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  350. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  351. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  352. data/test/cases/migration/table_and_index_test.rb +0 -24
  353. data/test/cases/relation/where_test2.rb +0 -36
  354. data/test/cases/type/decimal_test.rb +0 -56
  355. data/test/cases/type/unsigned_integer_test.rb +0 -18
  356. data/test/cases/xml_serialization_test.rb +0 -457
  357. data/test/fixtures/naked/csv/accounts.csv +0 -1
  358. data/test/schema/mysql_specific_schema.rb +0 -70
@@ -73,10 +73,15 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase
73
73
  assert_equal post.association(:comments), post.comments.where('1=1').the_association
74
74
  end
75
75
 
76
+ def test_association_with_default_scope
77
+ assert_raises OopsError do
78
+ posts(:welcome).comments.destroy_all
79
+ end
80
+ end
81
+
76
82
  private
77
83
 
78
84
  def extend!(model)
79
- builder = ActiveRecord::Associations::Builder::HasMany.new(model, :association_name, nil, {}) { }
80
- builder.define_extensions(model)
85
+ ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) { }
81
86
  end
82
87
  end
@@ -19,6 +19,7 @@ require 'models/professor'
19
19
  require 'models/treasure'
20
20
  require 'models/price_estimate'
21
21
  require 'models/club'
22
+ require 'models/user'
22
23
  require 'models/member'
23
24
  require 'models/membership'
24
25
  require 'models/sponsor'
@@ -146,6 +147,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
146
147
  assert_equal 1, country.treaties.count
147
148
  end
148
149
 
150
+ def test_join_table_composite_primary_key_should_not_warn
151
+ country = Country.new(:name => 'India')
152
+ country.country_id = 'c1'
153
+ country.save!
154
+
155
+ treaty = Treaty.new(:name => 'peace')
156
+ treaty.treaty_id = 't1'
157
+ warning = capture(:stderr) do
158
+ country.treaties << treaty
159
+ end
160
+ assert_no_match(/WARNING: Active Record does not support composite primary key\./, warning)
161
+ end
162
+
149
163
  def test_has_and_belongs_to_many
150
164
  david = Developer.find(1)
151
165
 
@@ -168,8 +182,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
168
182
  jamis.projects << action_controller
169
183
 
170
184
  assert_equal 2, jamis.projects.size
171
- assert_equal 2, jamis.projects(true).size
172
- assert_equal 2, action_controller.developers(true).size
185
+ assert_equal 2, jamis.projects.reload.size
186
+ assert_equal 2, action_controller.developers.reload.size
173
187
  end
174
188
 
175
189
  def test_adding_type_mismatch
@@ -187,9 +201,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
187
201
 
188
202
  action_controller.developers << jamis
189
203
 
190
- assert_equal 2, jamis.projects(true).size
204
+ assert_equal 2, jamis.projects.reload.size
191
205
  assert_equal 2, action_controller.developers.size
192
- assert_equal 2, action_controller.developers(true).size
206
+ assert_equal 2, action_controller.developers.reload.size
193
207
  end
194
208
 
195
209
  def test_adding_from_the_project_fixed_timestamp
@@ -203,9 +217,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
203
217
  action_controller.developers << jamis
204
218
 
205
219
  assert_equal updated_at, jamis.updated_at
206
- assert_equal 2, jamis.projects(true).size
220
+ assert_equal 2, jamis.projects.reload.size
207
221
  assert_equal 2, action_controller.developers.size
208
- assert_equal 2, action_controller.developers(true).size
222
+ assert_equal 2, action_controller.developers.reload.size
209
223
  end
210
224
 
211
225
  def test_adding_multiple
@@ -214,7 +228,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
214
228
  aredridel.projects.reload
215
229
  aredridel.projects.push(Project.find(1), Project.find(2))
216
230
  assert_equal 2, aredridel.projects.size
217
- assert_equal 2, aredridel.projects(true).size
231
+ assert_equal 2, aredridel.projects.reload.size
218
232
  end
219
233
 
220
234
  def test_adding_a_collection
@@ -223,7 +237,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
223
237
  aredridel.projects.reload
224
238
  aredridel.projects.concat([Project.find(1), Project.find(2)])
225
239
  assert_equal 2, aredridel.projects.size
226
- assert_equal 2, aredridel.projects(true).size
240
+ assert_equal 2, aredridel.projects.reload.size
227
241
  end
228
242
 
229
243
  def test_habtm_adding_before_save
@@ -238,7 +252,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
238
252
  assert_equal no_of_devels+1, Developer.count
239
253
  assert_equal no_of_projects+1, Project.count
240
254
  assert_equal 2, aredridel.projects.size
241
- assert_equal 2, aredridel.projects(true).size
255
+ assert_equal 2, aredridel.projects.reload.size
242
256
  end
243
257
 
244
258
  def test_habtm_saving_multiple_relationships
@@ -255,7 +269,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
255
269
  assert_equal developers, new_project.developers
256
270
  end
257
271
 
258
- def test_habtm_unique_order_preserved
272
+ def test_habtm_distinct_order_preserved
259
273
  assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
260
274
  assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
261
275
  end
@@ -360,7 +374,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
360
374
  assert_equal 'Yet Another Testing Title', another_post.title
361
375
  end
362
376
 
363
- def test_uniq_after_the_fact
377
+ def test_distinct_after_the_fact
364
378
  dev = developers(:jamis)
365
379
  dev.projects << projects(:active_record)
366
380
  dev.projects << projects(:active_record)
@@ -369,13 +383,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
369
383
  assert_equal 1, dev.projects.distinct.size
370
384
  end
371
385
 
372
- def test_uniq_before_the_fact
386
+ def test_distinct_before_the_fact
373
387
  projects(:active_record).developers << developers(:jamis)
374
388
  projects(:active_record).developers << developers(:david)
375
389
  assert_equal 3, projects(:active_record, :reload).developers.size
376
390
  end
377
391
 
378
- def test_uniq_option_prevents_duplicate_push
392
+ def test_distinct_option_prevents_duplicate_push
379
393
  project = projects(:active_record)
380
394
  project.developers << developers(:jamis)
381
395
  project.developers << developers(:david)
@@ -386,7 +400,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
386
400
  assert_equal 3, project.developers.size
387
401
  end
388
402
 
389
- def test_uniq_when_association_already_loaded
403
+ def test_distinct_when_association_already_loaded
390
404
  project = projects(:active_record)
391
405
  project.developers << [ developers(:jamis), developers(:david), developers(:jamis), developers(:david) ]
392
406
  assert_equal 3, Project.includes(:developers).find(project.id).developers.size
@@ -402,8 +416,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
402
416
  david.projects.delete(active_record)
403
417
 
404
418
  assert_equal 1, david.projects.size
405
- assert_equal 1, david.projects(true).size
406
- assert_equal 2, active_record.developers(true).size
419
+ assert_equal 1, david.projects.reload.size
420
+ assert_equal 2, active_record.developers.reload.size
407
421
  end
408
422
 
409
423
  def test_deleting_array
@@ -411,7 +425,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
411
425
  david.projects.reload
412
426
  david.projects.delete(Project.all.to_a)
413
427
  assert_equal 0, david.projects.size
414
- assert_equal 0, david.projects(true).size
428
+ assert_equal 0, david.projects.reload.size
415
429
  end
416
430
 
417
431
  def test_deleting_all
@@ -419,7 +433,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
419
433
  david.projects.reload
420
434
  david.projects.clear
421
435
  assert_equal 0, david.projects.size
422
- assert_equal 0, david.projects(true).size
436
+ assert_equal 0, david.projects.reload.size
423
437
  end
424
438
 
425
439
  def test_removing_associations_on_destroy
@@ -445,7 +459,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
445
459
  assert join_records.empty?
446
460
 
447
461
  assert_equal 1, david.reload.projects.size
448
- assert_equal 1, david.projects(true).size
462
+ assert_equal 1, david.projects.reload.size
449
463
  end
450
464
 
451
465
  def test_destroying_many
@@ -461,7 +475,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
461
475
  assert join_records.empty?
462
476
 
463
477
  assert_equal 0, david.reload.projects.size
464
- assert_equal 0, david.projects(true).size
478
+ assert_equal 0, david.projects.reload.size
465
479
  end
466
480
 
467
481
  def test_destroy_all
@@ -477,7 +491,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
477
491
  assert join_records.empty?
478
492
 
479
493
  assert david.projects.empty?
480
- assert david.projects(true).empty?
494
+ assert david.projects.reload.empty?
481
495
  end
482
496
 
483
497
  def test_destroy_associations_destroys_multiple_associations
@@ -493,11 +507,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
493
507
 
494
508
  join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
495
509
  assert join_records.empty?
496
- assert george.pirates(true).empty?
510
+ assert george.pirates.reload.empty?
497
511
 
498
512
  join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
499
513
  assert join_records.empty?
500
- assert george.treasures(true).empty?
514
+ assert george.treasures.reload.empty?
501
515
  end
502
516
 
503
517
  def test_associations_with_conditions
@@ -576,7 +590,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
576
590
 
577
591
  def test_dynamic_find_all_should_respect_readonly_access
578
592
  projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?}
579
- projects(:active_record).readonly_developers.each { |d| d.readonly? }
593
+ projects(:active_record).readonly_developers.each(&:readonly?)
580
594
  end
581
595
 
582
596
  def test_new_with_values_in_collection
@@ -665,7 +679,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
665
679
  end
666
680
 
667
681
  def test_habtm_respects_select
668
- categories(:technology).select_testing_posts(true).each do |o|
682
+ categories(:technology).select_testing_posts.reload.each do |o|
669
683
  assert_respond_to o, :correctness_marker
670
684
  end
671
685
  assert_respond_to categories(:technology).select_testing_posts.first, :correctness_marker
@@ -737,7 +751,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
737
751
 
738
752
  def test_get_ids_for_loaded_associations
739
753
  developer = developers(:david)
740
- developer.projects(true)
754
+ developer.projects.reload
741
755
  assert_queries(0) do
742
756
  developer.project_ids
743
757
  developer.project_ids
@@ -805,9 +819,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
805
819
  end
806
820
 
807
821
  def test_association_proxy_transaction_method_starts_transaction_in_association_class
808
- Post.expects(:transaction)
809
- Category.first.posts.transaction do
810
- # nothing
822
+ assert_called(Post, :transaction) do
823
+ Category.first.posts.transaction do
824
+ # nothing
825
+ end
811
826
  end
812
827
  end
813
828
 
@@ -826,12 +841,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
826
841
  assert_no_queries { david.projects.columns }
827
842
  end
828
843
 
829
- def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
844
+ def test_attributes_are_being_set_when_initialized_from_habtm_association_with_where_clause
830
845
  new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build
831
846
  assert_equal new_developer.name, "Marcelo"
832
847
  end
833
848
 
834
- def test_attributes_are_being_set_when_initialized_from_habm_association_with_multiple_where_clauses
849
+ def test_attributes_are_being_set_when_initialized_from_habtm_association_with_multiple_where_clauses
835
850
  new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build
836
851
  assert_equal new_developer.name, "Marcelo"
837
852
  assert_equal new_developer.salary, 90_000
@@ -924,11 +939,17 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
924
939
  end
925
940
 
926
941
  def test_with_symbol_class_name
927
- assert_nothing_raised NoMethodError do
942
+ assert_nothing_raised do
928
943
  DeveloperWithSymbolClassName.new
929
944
  end
930
945
  end
931
946
 
947
+ def test_association_force_reload_with_only_true_is_deprecated
948
+ developer = Developer.find(1)
949
+
950
+ assert_deprecated { developer.projects(true) }
951
+ end
952
+
932
953
  def test_alternate_database
933
954
  professor = Professor.create(name: "Plum")
934
955
  course = Course.create(name: "Forensics")
@@ -969,4 +990,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
969
990
  assert preloaded_first_project.salaried_developers.loaded?, true
970
991
  assert_equal first_project.salaried_developers.size, preloaded_first_project.salaried_developers.size
971
992
  end
993
+
994
+ def test_has_and_belongs_to_many_is_useable_with_belongs_to_required_by_default
995
+ assert_difference "Project.first.developers_required_by_default.size", 1 do
996
+ Project.first.developers_required_by_default.create!(name: "Sean", salary: 50000)
997
+ end
998
+ end
999
+
1000
+ def test_association_name_is_the_same_as_join_table_name
1001
+ user = User.create!
1002
+ assert_nothing_raised { user.jobs_pool.clear }
1003
+ end
972
1004
  end
@@ -30,6 +30,7 @@ require 'models/college'
30
30
  require 'models/student'
31
31
  require 'models/pirate'
32
32
  require 'models/ship'
33
+ require 'models/ship_part'
33
34
  require 'models/treasure'
34
35
  require 'models/parrot'
35
36
  require 'models/tyre'
@@ -39,7 +40,7 @@ require 'models/zine'
39
40
  require 'models/interest'
40
41
 
41
42
  class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase
42
- fixtures :authors, :posts, :comments, :author_addresses
43
+ fixtures :authors, :posts, :comments
43
44
 
44
45
  def test_should_generate_valid_sql
45
46
  author = authors(:david)
@@ -60,7 +61,7 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
60
61
  assert_equal 2, subscriber.subscriptions.size
61
62
  end
62
63
 
63
- assert_equal subscriber.subscriptions, Subscription.where(subscriber_id: 'webster132')
64
+ assert_equal Subscription.where(subscriber_id: "webster132"), subscriber.subscriptions
64
65
  end
65
66
 
66
67
  def test_association_primary_key_on_new_record_should_fetch_with_query
@@ -71,12 +72,23 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
71
72
  assert_equal 1, author.essays.size
72
73
  end
73
74
 
74
- assert_equal author.essays, Essay.where(writer_id: "David")
75
+ assert_equal Essay.where(writer_id: "David"), author.essays
75
76
  end
76
77
 
77
78
  def test_has_many_custom_primary_key
78
79
  david = authors(:david)
79
- assert_equal david.essays, Essay.where(writer_id: "David")
80
+ assert_equal Essay.where(writer_id: "David"), david.essays
81
+ end
82
+
83
+ def test_ids_on_unloaded_association_with_custom_primary_key
84
+ david = people(:david)
85
+ assert_equal Essay.where(writer_id: "David").pluck(:id), david.essay_ids
86
+ end
87
+
88
+ def test_ids_on_loaded_association_with_custom_primary_key
89
+ david = people(:david)
90
+ david.essays.load
91
+ assert_equal Essay.where(writer_id: "David").pluck(:id), david.essay_ids
80
92
  end
81
93
 
82
94
  def test_has_many_assignment_with_custom_primary_key
@@ -164,6 +176,32 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
164
176
  assert_equal college.students, Student.where(active: true, college_id: college.id)
165
177
  end
166
178
 
179
+ def test_add_record_to_collection_should_change_its_updated_at
180
+ ship = Ship.create(name: 'dauntless')
181
+ part = ShipPart.create(name: 'cockpit')
182
+ updated_at = part.updated_at
183
+
184
+ travel(1.second) do
185
+ ship.parts << part
186
+ end
187
+
188
+ assert_equal part.ship, ship
189
+ assert_not_equal part.updated_at, updated_at
190
+ end
191
+
192
+ def test_clear_collection_should_not_change_updated_at
193
+ # GH#17161: .clear calls delete_all (and returns the association),
194
+ # which is intended to not touch associated objects's updated_at field
195
+ ship = Ship.create(name: 'dauntless')
196
+ part = ShipPart.create(name: 'cockpit', ship_id: ship.id)
197
+
198
+ ship.parts.clear
199
+ part.reload
200
+
201
+ assert_equal nil, part.ship
202
+ assert !part.updated_at_changed?
203
+ end
204
+
167
205
  def test_create_from_association_should_respect_default_scope
168
206
  car = Car.create(:name => 'honda')
169
207
  assert_equal 'honda', car.name
@@ -176,9 +214,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
176
214
 
177
215
  bulb = car.bulbs.create
178
216
  assert_equal 'defaulty', bulb.name
217
+ end
218
+
219
+ def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
220
+ car = Car.create(name: 'honda')
179
221
 
180
- bulb = car.bulbs.create(:name => 'exotic')
222
+ bulb = car.bulbs.build(name: 'exotic')
181
223
  assert_equal 'exotic', bulb.name
224
+
225
+ bulb = car.bulbs.create(name: 'exotic')
226
+ assert_equal 'exotic', bulb.name
227
+
228
+ bulb = car.awesome_bulbs.build(frickinawesome: false)
229
+ assert_equal false, bulb.frickinawesome
230
+
231
+ bulb = car.awesome_bulbs.create(frickinawesome: false)
232
+ assert_equal false, bulb.frickinawesome
182
233
  end
183
234
 
184
235
  def test_build_from_association_should_respect_scope
@@ -320,16 +371,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
320
371
  # would be convenient), because this would cause that scope to be applied to any callbacks etc.
321
372
  def test_build_and_create_should_not_happen_within_scope
322
373
  car = cars(:honda)
323
- scoped_count = car.foo_bulbs.where_values.count
374
+ scope = car.foo_bulbs.where_values_hash
324
375
 
325
376
  bulb = car.foo_bulbs.build
326
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
377
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
327
378
 
328
379
  bulb = car.foo_bulbs.create
329
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
380
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
330
381
 
331
382
  bulb = car.foo_bulbs.create!
332
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
383
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
333
384
  end
334
385
 
335
386
  def test_no_sql_should_be_fired_if_association_already_loaded
@@ -367,6 +418,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
367
418
  bulbs.forty_two({})
368
419
  end
369
420
 
421
+ assert_no_queries do
422
+ bulbs.third_to_last()
423
+ bulbs.third_to_last({})
424
+ end
425
+
426
+ assert_no_queries do
427
+ bulbs.second_to_last()
428
+ bulbs.second_to_last({})
429
+ end
430
+
370
431
  assert_no_queries do
371
432
  bulbs.last()
372
433
  bulbs.last({})
@@ -388,6 +449,26 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
388
449
  assert_equal person, person.readers.first.person
389
450
  end
390
451
 
452
+ def test_update_all_respects_association_scope
453
+ person = Person.new
454
+ person.first_name = 'Naruto'
455
+ person.references << Reference.new
456
+ person.id = 10
457
+ person.references
458
+ person.save!
459
+ assert_equal 1, person.references.update_all(favourite: true)
460
+ end
461
+
462
+ def test_exists_respects_association_scope
463
+ person = Person.new
464
+ person.first_name = 'Sasuke'
465
+ person.references << Reference.new
466
+ person.id = 10
467
+ person.references
468
+ person.save!
469
+ assert_predicate person.references, :exists?
470
+ end
471
+
391
472
  def force_signal37_to_load_all_clients_of_firm
392
473
  companies(:first_firm).clients_of_firm.each {|f| }
393
474
  end
@@ -508,10 +589,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
508
589
  end
509
590
 
510
591
  def test_update_all_on_association_accessed_before_save
511
- firm = Firm.new(name: 'Firm')
592
+ firm = Firm.new(name: "Firm")
593
+ firm.clients << Client.first
594
+ firm.save!
595
+ assert_equal firm.clients.count, firm.clients.update_all(description: "Great!")
596
+ end
597
+
598
+ def test_update_all_on_association_accessed_before_save_with_explicit_foreign_key
599
+ firm = Firm.new(name: "Firm", id: 100)
512
600
  firm.clients << Client.first
513
601
  firm.save!
514
- assert_equal firm.clients.count, firm.clients.update_all(description: 'Great!')
602
+ assert_equal firm.clients.count, firm.clients.update_all(description: "Great!")
515
603
  end
516
604
 
517
605
  def test_belongs_to_sanity
@@ -539,6 +627,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
539
627
  assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
540
628
  end
541
629
 
630
+ def test_find_one_message_on_primary_key
631
+ firm = Firm.all.merge!(order: "id").first
632
+
633
+ e = assert_raises(ActiveRecord::RecordNotFound) do
634
+ firm.clients.find(0)
635
+ end
636
+ assert_equal 0, e.id
637
+ assert_equal "id", e.primary_key
638
+ assert_equal "Client", e.model
639
+ assert_match (/\ACouldn't find Client with 'id'=0/), e.message
640
+ end
641
+
542
642
  def test_find_ids_and_inverse_of
543
643
  force_signal37_to_load_all_clients_of_firm
544
644
 
@@ -669,7 +769,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
669
769
  natural = Client.new("name" => "Natural Company")
670
770
  companies(:first_firm).clients_of_firm << natural
671
771
  assert_equal 3, companies(:first_firm).clients_of_firm.size # checking via the collection
672
- assert_equal 3, companies(:first_firm).clients_of_firm(true).size # checking using the db
772
+ assert_equal 3, companies(:first_firm).clients_of_firm.reload.size # checking using the db
673
773
  assert_equal natural, companies(:first_firm).clients_of_firm.last
674
774
  end
675
775
 
@@ -724,7 +824,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
724
824
  force_signal37_to_load_all_clients_of_firm
725
825
  companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
726
826
  assert_equal 4, companies(:first_firm).clients_of_firm.size
727
- assert_equal 4, companies(:first_firm).clients_of_firm(true).size
827
+ assert_equal 4, companies(:first_firm).clients_of_firm.reload.size
728
828
  end
729
829
 
730
830
  def test_transactions_when_adding_to_persisted
@@ -736,7 +836,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
736
836
  rescue Client::RaisedOnSave
737
837
  end
738
838
 
739
- assert !companies(:first_firm).clients_of_firm(true).include?(good)
839
+ assert !companies(:first_firm).clients_of_firm.reload.include?(good)
740
840
  end
741
841
 
742
842
  def test_transactions_when_adding_to_new_record
@@ -868,12 +968,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
868
968
  new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
869
969
  assert new_client.persisted?
870
970
  assert_equal new_client, companies(:first_firm).clients_of_firm.last
871
- assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
971
+ assert_equal new_client, companies(:first_firm).clients_of_firm.reload.last
872
972
  end
873
973
 
874
974
  def test_create_many
875
975
  companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
876
- assert_equal 4, companies(:first_firm).clients_of_firm(true).size
976
+ assert_equal 4, companies(:first_firm).clients_of_firm.reload.size
877
977
  end
878
978
 
879
979
  def test_create_followed_by_save_does_not_load_target
@@ -886,7 +986,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
886
986
  force_signal37_to_load_all_clients_of_firm
887
987
  companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
888
988
  assert_equal 1, companies(:first_firm).clients_of_firm.size
889
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
989
+ assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
890
990
  end
891
991
 
892
992
  def test_deleting_before_save
@@ -902,7 +1002,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
902
1002
  # option is not given on the association.
903
1003
  ship = Ship.create(name: 'Countless', treasures_count: 10)
904
1004
 
905
- assert_not ship.treasures.instance_variable_get('@association').send(:has_cached_counter?)
1005
+ assert_not Ship.reflect_on_association(:treasures).has_cached_counter?
906
1006
 
907
1007
  # Count should come from sql count() of treasures rather than treasures_count attribute
908
1008
  assert_equal ship.treasures.size, 0
@@ -1042,7 +1142,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1042
1142
  assert_equal 3, companies(:first_firm).clients_of_firm.size
1043
1143
  companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1], companies(:first_firm).clients_of_firm[2]])
1044
1144
  assert_equal 0, companies(:first_firm).clients_of_firm.size
1045
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
1145
+ assert_equal 0, companies(:first_firm).clients_of_firm.reload.size
1046
1146
  end
1047
1147
 
1048
1148
  def test_delete_all
@@ -1063,7 +1163,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1063
1163
  companies(:first_firm).clients_of_firm.reset
1064
1164
  companies(:first_firm).clients_of_firm.delete_all
1065
1165
  assert_equal 0, companies(:first_firm).clients_of_firm.size
1066
- assert_equal 0, companies(:first_firm).clients_of_firm(true).size
1166
+ assert_equal 0, companies(:first_firm).clients_of_firm.reload.size
1067
1167
  end
1068
1168
 
1069
1169
  def test_transaction_when_deleting_persisted
@@ -1077,7 +1177,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1077
1177
  rescue Client::RaisedOnDestroy
1078
1178
  end
1079
1179
 
1080
- assert_equal [good, bad], companies(:first_firm).clients_of_firm(true)
1180
+ assert_equal [good, bad], companies(:first_firm).clients_of_firm.reload
1081
1181
  end
1082
1182
 
1083
1183
  def test_transaction_when_deleting_new_record
@@ -1097,7 +1197,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1097
1197
  firm.clients_of_firm.clear
1098
1198
 
1099
1199
  assert_equal 0, firm.clients_of_firm.size
1100
- assert_equal 0, firm.clients_of_firm(true).size
1200
+ assert_equal 0, firm.clients_of_firm.reload.size
1101
1201
  assert_equal [], Client.destroyed_client_ids[firm.id]
1102
1202
 
1103
1203
  # Should not be destroyed since the association is not dependent.
@@ -1133,7 +1233,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1133
1233
  firm.dependent_clients_of_firm.clear
1134
1234
 
1135
1235
  assert_equal 0, firm.dependent_clients_of_firm.size
1136
- assert_equal 0, firm.dependent_clients_of_firm(true).size
1236
+ assert_equal 0, firm.dependent_clients_of_firm.reload.size
1137
1237
  assert_equal [], Client.destroyed_client_ids[firm.id]
1138
1238
 
1139
1239
  # Should be destroyed since the association is dependent.
@@ -1166,7 +1266,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1166
1266
  firm.exclusively_dependent_clients_of_firm.clear
1167
1267
 
1168
1268
  assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
1169
- assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
1269
+ assert_equal 0, firm.exclusively_dependent_clients_of_firm.reload.size
1170
1270
  # no destroy-filters should have been called
1171
1271
  assert_equal [], Client.destroyed_client_ids[firm.id]
1172
1272
 
@@ -1215,7 +1315,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1215
1315
  # break the vanilla firm_id foreign key
1216
1316
  assert_equal 3, firm.clients.count
1217
1317
  firm.clients.first.update_columns(firm_id: nil)
1218
- assert_equal 2, firm.clients(true).count
1318
+ assert_equal 2, firm.clients.reload.count
1219
1319
  assert_equal 2, firm.clients_using_primary_key_with_delete_all.count
1220
1320
  old_record = firm.clients_using_primary_key_with_delete_all.first
1221
1321
  firm = Firm.first
@@ -1241,7 +1341,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1241
1341
  firm.clients_of_firm.clear
1242
1342
 
1243
1343
  assert_equal 0, firm.clients_of_firm.size
1244
- assert_equal 0, firm.clients_of_firm(true).size
1344
+ assert_equal 0, firm.clients_of_firm.reload.size
1245
1345
  end
1246
1346
 
1247
1347
  def test_deleting_a_item_which_is_not_in_the_collection
@@ -1249,11 +1349,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1249
1349
  summit = Client.find_by_name('Summit')
1250
1350
  companies(:first_firm).clients_of_firm.delete(summit)
1251
1351
  assert_equal 2, companies(:first_firm).clients_of_firm.size
1252
- assert_equal 2, companies(:first_firm).clients_of_firm(true).size
1352
+ assert_equal 2, companies(:first_firm).clients_of_firm.reload.size
1253
1353
  assert_equal 2, summit.client_of
1254
1354
  end
1255
1355
 
1256
- def test_deleting_by_fixnum_id
1356
+ def test_deleting_by_integer_id
1257
1357
  david = Developer.find(1)
1258
1358
 
1259
1359
  assert_difference 'david.projects.count', -1 do
@@ -1287,10 +1387,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1287
1387
  end
1288
1388
 
1289
1389
  assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
1290
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
1390
+ assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
1291
1391
  end
1292
1392
 
1293
- def test_destroying_by_fixnum_id
1393
+ def test_destroying_by_integer_id
1294
1394
  force_signal37_to_load_all_clients_of_firm
1295
1395
 
1296
1396
  assert_difference "Client.count", -1 do
@@ -1298,7 +1398,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1298
1398
  end
1299
1399
 
1300
1400
  assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
1301
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
1401
+ assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
1302
1402
  end
1303
1403
 
1304
1404
  def test_destroying_by_string_id
@@ -1309,7 +1409,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1309
1409
  end
1310
1410
 
1311
1411
  assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
1312
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
1412
+ assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
1313
1413
  end
1314
1414
 
1315
1415
  def test_destroying_a_collection
@@ -1322,7 +1422,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1322
1422
  end
1323
1423
 
1324
1424
  assert_equal 1, companies(:first_firm).reload.clients_of_firm.size
1325
- assert_equal 1, companies(:first_firm).clients_of_firm(true).size
1425
+ assert_equal 1, companies(:first_firm).clients_of_firm.reload.size
1326
1426
  end
1327
1427
 
1328
1428
  def test_destroy_all
@@ -1331,9 +1431,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1331
1431
  assert !clients.empty?, "37signals has clients after load"
1332
1432
  destroyed = companies(:first_firm).clients_of_firm.destroy_all
1333
1433
  assert_equal clients.sort_by(&:id), destroyed.sort_by(&:id)
1334
- assert destroyed.all? { |client| client.frozen? }, "destroyed clients should be frozen"
1434
+ assert destroyed.all?(&:frozen?), "destroyed clients should be frozen"
1335
1435
  assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
1336
- assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
1436
+ assert companies(:first_firm).clients_of_firm.reload.empty?, "37signals has no clients after destroy all and refresh"
1337
1437
  end
1338
1438
 
1339
1439
  def test_dependence
@@ -1369,7 +1469,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1369
1469
  assert_nothing_raised { topic.destroy }
1370
1470
  end
1371
1471
 
1372
- uses_transaction :test_dependence_with_transaction_support_on_failure
1373
1472
  def test_dependence_with_transaction_support_on_failure
1374
1473
  firm = companies(:first_firm)
1375
1474
  clients = firm.clients
@@ -1411,6 +1510,26 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1411
1510
  assert firm.companies.exists?(:name => 'child')
1412
1511
  end
1413
1512
 
1513
+ def test_restrict_with_error_is_deprecated_using_key_many
1514
+ I18n.backend = I18n::Backend::Simple.new
1515
+ I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { many: 'message for deprecated key' } } } }
1516
+
1517
+ firm = RestrictedWithErrorFirm.create!(name: 'restrict')
1518
+ firm.companies.create(name: 'child')
1519
+
1520
+ assert !firm.companies.empty?
1521
+
1522
+ assert_deprecated { firm.destroy }
1523
+
1524
+ assert !firm.errors.empty?
1525
+
1526
+ assert_equal 'message for deprecated key', firm.errors[:base].first
1527
+ assert RestrictedWithErrorFirm.exists?(name: 'restrict')
1528
+ assert firm.companies.exists?(name: 'child')
1529
+ ensure
1530
+ I18n.backend.reload!
1531
+ end
1532
+
1414
1533
  def test_restrict_with_error
1415
1534
  firm = RestrictedWithErrorFirm.create!(:name => 'restrict')
1416
1535
  firm.companies.create(:name => 'child')
@@ -1426,6 +1545,25 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1426
1545
  assert firm.companies.exists?(:name => 'child')
1427
1546
  end
1428
1547
 
1548
+ def test_restrict_with_error_with_locale
1549
+ I18n.backend = I18n::Backend::Simple.new
1550
+ I18n.backend.store_translations 'en', activerecord: {attributes: {restricted_with_error_firm: {companies: 'client companies'}}}
1551
+ firm = RestrictedWithErrorFirm.create!(name: 'restrict')
1552
+ firm.companies.create(name: 'child')
1553
+
1554
+ assert !firm.companies.empty?
1555
+
1556
+ firm.destroy
1557
+
1558
+ assert !firm.errors.empty?
1559
+
1560
+ assert_equal "Cannot delete record because dependent client companies exist", firm.errors[:base].first
1561
+ assert RestrictedWithErrorFirm.exists?(name: 'restrict')
1562
+ assert firm.companies.exists?(name: 'child')
1563
+ ensure
1564
+ I18n.backend.reload!
1565
+ end
1566
+
1429
1567
  def test_included_in_collection
1430
1568
  assert_equal true, companies(:first_firm).clients.include?(Client.find(2))
1431
1569
  end
@@ -1488,6 +1626,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1488
1626
  assert_queries(0, ignore_none: true) do
1489
1627
  firm.clients = []
1490
1628
  end
1629
+
1630
+ assert_equal [], firm.send('clients=', [])
1491
1631
  end
1492
1632
 
1493
1633
  def test_transactions_when_replacing_on_persisted
@@ -1501,7 +1641,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1501
1641
  rescue Client::RaisedOnSave
1502
1642
  end
1503
1643
 
1504
- assert_equal [good], companies(:first_firm).clients_of_firm(true)
1644
+ assert_equal [good], companies(:first_firm).clients_of_firm.reload
1505
1645
  end
1506
1646
 
1507
1647
  def test_transactions_when_replacing_on_new_record
@@ -1517,7 +1657,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1517
1657
 
1518
1658
  def test_get_ids_for_loaded_associations
1519
1659
  company = companies(:first_firm)
1520
- company.clients(true)
1660
+ company.clients.reload
1521
1661
  assert_queries(0) do
1522
1662
  company.client_ids
1523
1663
  company.client_ids
@@ -1571,7 +1711,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1571
1711
  firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
1572
1712
  firm.save!
1573
1713
 
1574
- assert_equal 2, firm.clients(true).size
1714
+ assert_equal 2, firm.clients.reload.size
1575
1715
  assert_equal true, firm.clients.include?(companies(:second_client))
1576
1716
  end
1577
1717
 
@@ -1741,6 +1881,82 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1741
1881
  assert_equal 3, firm.clients.size
1742
1882
  end
1743
1883
 
1884
+ def test_calling_none_should_count_instead_of_loading_association
1885
+ firm = companies(:first_firm)
1886
+ assert_queries(1) do
1887
+ firm.clients.none? # use count query
1888
+ end
1889
+ assert !firm.clients.loaded?
1890
+ end
1891
+
1892
+ def test_calling_none_on_loaded_association_should_not_use_query
1893
+ firm = companies(:first_firm)
1894
+ firm.clients.collect # force load
1895
+ assert_no_queries { assert ! firm.clients.none? }
1896
+ end
1897
+
1898
+ def test_calling_none_should_defer_to_collection_if_using_a_block
1899
+ firm = companies(:first_firm)
1900
+ assert_queries(1) do
1901
+ firm.clients.expects(:size).never
1902
+ firm.clients.none? { true }
1903
+ end
1904
+ assert firm.clients.loaded?
1905
+ end
1906
+
1907
+ def test_calling_none_should_return_true_if_none
1908
+ firm = companies(:another_firm)
1909
+ assert firm.clients_like_ms.none?
1910
+ assert_equal 0, firm.clients_like_ms.size
1911
+ end
1912
+
1913
+ def test_calling_none_should_return_false_if_any
1914
+ firm = companies(:first_firm)
1915
+ assert !firm.limited_clients.none?
1916
+ assert_equal 1, firm.limited_clients.size
1917
+ end
1918
+
1919
+ def test_calling_one_should_count_instead_of_loading_association
1920
+ firm = companies(:first_firm)
1921
+ assert_queries(1) do
1922
+ firm.clients.one? # use count query
1923
+ end
1924
+ assert !firm.clients.loaded?
1925
+ end
1926
+
1927
+ def test_calling_one_on_loaded_association_should_not_use_query
1928
+ firm = companies(:first_firm)
1929
+ firm.clients.collect # force load
1930
+ assert_no_queries { assert ! firm.clients.one? }
1931
+ end
1932
+
1933
+ def test_calling_one_should_defer_to_collection_if_using_a_block
1934
+ firm = companies(:first_firm)
1935
+ assert_queries(1) do
1936
+ firm.clients.expects(:size).never
1937
+ firm.clients.one? { true }
1938
+ end
1939
+ assert firm.clients.loaded?
1940
+ end
1941
+
1942
+ def test_calling_one_should_return_false_if_zero
1943
+ firm = companies(:another_firm)
1944
+ assert ! firm.clients_like_ms.one?
1945
+ assert_equal 0, firm.clients_like_ms.size
1946
+ end
1947
+
1948
+ def test_calling_one_should_return_true_if_one
1949
+ firm = companies(:first_firm)
1950
+ assert firm.limited_clients.one?
1951
+ assert_equal 1, firm.limited_clients.size
1952
+ end
1953
+
1954
+ def test_calling_one_should_return_false_if_more_than_one
1955
+ firm = companies(:first_firm)
1956
+ assert ! firm.clients.one?
1957
+ assert_equal 3, firm.clients.size
1958
+ end
1959
+
1744
1960
  def test_joins_with_namespaced_model_should_use_correct_type
1745
1961
  old = ActiveRecord::Base.store_full_sti_class
1746
1962
  ActiveRecord::Base.store_full_sti_class = true
@@ -1990,7 +2206,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1990
2206
  test "association with extend option with multiple extensions" do
1991
2207
  post = posts(:welcome)
1992
2208
  assert_equal "lifo", post.comments_with_extend_2.author
1993
- assert_equal "hello", post.comments_with_extend_2.greeting
2209
+ assert_equal "hullo", post.comments_with_extend_2.greeting
2210
+ end
2211
+
2212
+ test "extend option affects per association" do
2213
+ post = posts(:welcome)
2214
+ assert_equal "lifo", post.comments_with_extend.author
2215
+ assert_equal "lifo", post.comments_with_extend_2.author
2216
+ assert_equal "hello", post.comments_with_extend.greeting
2217
+ assert_equal "hullo", post.comments_with_extend_2.greeting
1994
2218
  end
1995
2219
 
1996
2220
  test "delete record with complex joins" do
@@ -2050,8 +2274,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2050
2274
  car = Car.create!
2051
2275
  bulb = Bulb.create! name: "other", car: car
2052
2276
 
2053
- assert_equal bulb, Car.find(car.id).all_bulbs.first
2054
- assert_equal bulb, Car.includes(:all_bulbs).find(car.id).all_bulbs.first
2277
+ assert_equal [bulb], Car.find(car.id).all_bulbs
2278
+ assert_equal [bulb], Car.includes(:all_bulbs).find(car.id).all_bulbs
2279
+ assert_equal [bulb], Car.eager_load(:all_bulbs).find(car.id).all_bulbs
2055
2280
  end
2056
2281
 
2057
2282
  test "raises RecordNotDestroyed when replaced child can't be destroyed" do
@@ -2103,7 +2328,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2103
2328
  assert_equal [], authors(:david).posts_with_signature.map(&:title)
2104
2329
  end
2105
2330
 
2106
- test 'associations autosaves when object is already persited' do
2331
+ test 'associations autosaves when object is already persisted' do
2107
2332
  bulb = Bulb.create!
2108
2333
  tyre = Tyre.create!
2109
2334
 
@@ -2179,4 +2404,98 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2179
2404
 
2180
2405
  assert_equal [first_bulb, second_bulb], car.bulbs
2181
2406
  end
2407
+
2408
+ test "prevent double insertion of new object when the parent association loaded in the after save callback" do
2409
+ reset_callbacks(:save, Bulb) do
2410
+ Bulb.after_save { |record| record.car.bulbs.load }
2411
+
2412
+ car = Car.create!
2413
+ car.bulbs << Bulb.new
2414
+
2415
+ assert_equal 1, car.bulbs.size
2416
+ end
2417
+ end
2418
+
2419
+ test "prevent double firing the before save callback of new object when the parent association saved in the callback" do
2420
+ reset_callbacks(:save, Bulb) do
2421
+ count = 0
2422
+ Bulb.before_save { |record| record.car.save && count += 1 }
2423
+
2424
+ car = Car.create!
2425
+ car.bulbs.create!
2426
+
2427
+ assert_equal 1, count
2428
+ end
2429
+ end
2430
+
2431
+ def test_association_force_reload_with_only_true_is_deprecated
2432
+ company = Company.find(1)
2433
+
2434
+ assert_deprecated { company.clients_of_firm(true) }
2435
+ end
2436
+
2437
+ class AuthorWithErrorDestroyingAssociation < ActiveRecord::Base
2438
+ self.table_name = "authors"
2439
+ has_many :posts_with_error_destroying,
2440
+ class_name: "PostWithErrorDestroying",
2441
+ foreign_key: :author_id,
2442
+ dependent: :destroy
2443
+ end
2444
+
2445
+ class PostWithErrorDestroying < ActiveRecord::Base
2446
+ self.table_name = "posts"
2447
+ self.inheritance_column = nil
2448
+ before_destroy -> { throw :abort }
2449
+ end
2450
+
2451
+ def test_destroy_does_not_raise_when_association_errors_on_destroy
2452
+ assert_no_difference "AuthorWithErrorDestroyingAssociation.count" do
2453
+ author = AuthorWithErrorDestroyingAssociation.first
2454
+
2455
+ assert_not author.destroy
2456
+ end
2457
+ end
2458
+
2459
+ def test_destroy_with_bang_bubbles_errors_from_associations
2460
+ error = assert_raises ActiveRecord::RecordNotDestroyed do
2461
+ AuthorWithErrorDestroyingAssociation.first.destroy!
2462
+ end
2463
+
2464
+ assert_instance_of PostWithErrorDestroying, error.record
2465
+ end
2466
+
2467
+ def test_ids_reader_memoization
2468
+ car = Car.create!(name: 'Tofaş')
2469
+ bulb = Bulb.create!(car: car)
2470
+
2471
+ assert_equal [bulb.id], car.bulb_ids
2472
+ assert_no_queries { car.bulb_ids }
2473
+ end
2474
+
2475
+ def test_loading_association_in_validate_callback_doesnt_affect_persistence
2476
+ reset_callbacks(:validation, Bulb) do
2477
+ Bulb.after_validation { |record| record.car.bulbs.load }
2478
+
2479
+ car = Car.create!(name: "Car")
2480
+ bulb = car.bulbs.create!
2481
+
2482
+ assert_equal [bulb], car.bulbs
2483
+ end
2484
+ end
2485
+
2486
+ private
2487
+
2488
+ def reset_callbacks(kind, klass)
2489
+ old_callbacks = {}
2490
+ old_callbacks[klass] = klass.send("_#{kind}_callbacks").dup
2491
+ klass.subclasses.each do |subclass|
2492
+ old_callbacks[subclass] = subclass.send("_#{kind}_callbacks").dup
2493
+ end
2494
+ yield
2495
+ ensure
2496
+ klass.send("_#{kind}_callbacks=", old_callbacks[klass])
2497
+ klass.subclasses.each do |subclass|
2498
+ subclass.send("_#{kind}_callbacks=", old_callbacks[subclass])
2499
+ end
2500
+ end
2182
2501
  end