ibm_db 3.0.4-x86-mingw32 → 3.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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -1
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/README +225 -225
  6. data/ext/Makefile.nt32 +181 -181
  7. data/ext/Makefile.nt32.191 +212 -212
  8. data/ext/extconf.rb +291 -291
  9. data/ext/ibm_db.c +11887 -11884
  10. data/ext/ruby_ibm_db.h +241 -241
  11. data/ext/ruby_ibm_db_cli.c +866 -866
  12. data/ext/ruby_ibm_db_cli.h +500 -500
  13. data/init.rb +41 -41
  14. data/lib/IBM_DB.rb +27 -27
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3177 -3177
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  18. data/lib/mswin32/ibm_db.rb +122 -122
  19. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  20. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  21. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  22. data/test/active_record/connection_adapters/fake_adapter.rb +46 -46
  23. data/test/assets/example.log +1 -1
  24. data/test/assets/test.txt +1 -1
  25. data/test/cases/adapter_test.rb +276 -261
  26. data/test/cases/aggregations_test.rb +158 -158
  27. data/test/cases/ar_schema_test.rb +161 -161
  28. data/test/cases/associations/association_scope_test.rb +21 -21
  29. data/test/cases/associations/belongs_to_associations_test.rb +1029 -1029
  30. data/test/cases/associations/callbacks_test.rb +192 -192
  31. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  32. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -26
  33. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  34. data/test/cases/associations/eager_load_nested_include_test.rb +128 -128
  35. data/test/cases/associations/eager_singularization_test.rb +148 -148
  36. data/test/cases/associations/eager_test.rb +1429 -1411
  37. data/test/cases/associations/extension_test.rb +82 -82
  38. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +972 -932
  39. data/test/cases/associations/has_many_associations_test.rb +2182 -2162
  40. data/test/cases/associations/has_many_through_associations_test.rb +1204 -1204
  41. data/test/cases/associations/has_one_associations_test.rb +610 -610
  42. data/test/cases/associations/has_one_through_associations_test.rb +380 -380
  43. data/test/cases/associations/inner_join_association_test.rb +139 -139
  44. data/test/cases/associations/inverse_associations_test.rb +706 -693
  45. data/test/cases/associations/join_model_test.rb +754 -754
  46. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  47. data/test/cases/associations/required_test.rb +82 -82
  48. data/test/cases/associations_test.rb +380 -380
  49. data/test/cases/attribute_decorators_test.rb +125 -125
  50. data/test/cases/attribute_methods/read_test.rb +60 -60
  51. data/test/cases/attribute_methods/serialization_test.rb +29 -29
  52. data/test/cases/attribute_methods_test.rb +952 -952
  53. data/test/cases/attribute_set_test.rb +210 -200
  54. data/test/cases/attribute_test.rb +180 -180
  55. data/test/cases/attributes_test.rb +136 -136
  56. data/test/cases/autosave_association_test.rb +1595 -1595
  57. data/test/cases/base_test.rb +1664 -1638
  58. data/test/cases/batches_test.rb +212 -212
  59. data/test/cases/binary_test.rb +52 -52
  60. data/test/cases/bind_parameter_test.rb +100 -100
  61. data/test/cases/calculations_test.rb +646 -646
  62. data/test/cases/callbacks_test.rb +543 -543
  63. data/test/cases/clone_test.rb +40 -40
  64. data/test/cases/coders/yaml_column_test.rb +63 -63
  65. data/test/cases/column_alias_test.rb +17 -17
  66. data/test/cases/column_definition_test.rb +123 -123
  67. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -54
  68. data/test/cases/connection_adapters/connection_handler_test.rb +53 -53
  69. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  70. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -293
  71. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -65
  72. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  73. data/test/cases/connection_adapters/schema_cache_test.rb +56 -56
  74. data/test/cases/connection_adapters/type_lookup_test.rb +110 -110
  75. data/test/cases/connection_management_test.rb +122 -122
  76. data/test/cases/connection_pool_test.rb +346 -346
  77. data/test/cases/connection_specification/resolver_test.rb +116 -116
  78. data/test/cases/core_test.rb +112 -112
  79. data/test/cases/counter_cache_test.rb +209 -209
  80. data/test/cases/custom_locking_test.rb +17 -17
  81. data/test/cases/database_statements_test.rb +19 -19
  82. data/test/cases/date_time_test.rb +61 -61
  83. data/test/cases/defaults_test.rb +223 -223
  84. data/test/cases/dirty_test.rb +785 -775
  85. data/test/cases/disconnected_test.rb +28 -28
  86. data/test/cases/dup_test.rb +157 -157
  87. data/test/cases/enum_test.rb +290 -290
  88. data/test/cases/explain_subscriber_test.rb +64 -64
  89. data/test/cases/explain_test.rb +76 -76
  90. data/test/cases/finder_respond_to_test.rb +60 -60
  91. data/test/cases/finder_test.rb +1169 -1166
  92. data/test/cases/fixture_set/file_test.rb +138 -138
  93. data/test/cases/fixtures_test.rb +908 -897
  94. data/test/cases/forbidden_attributes_protection_test.rb +99 -99
  95. data/test/cases/habtm_destroy_order_test.rb +61 -61
  96. data/test/cases/helper.rb +210 -210
  97. data/test/cases/hot_compatibility_test.rb +54 -54
  98. data/test/cases/i18n_test.rb +45 -45
  99. data/test/cases/inheritance_test.rb +375 -375
  100. data/test/cases/integration_test.rb +139 -139
  101. data/test/cases/invalid_connection_test.rb +22 -22
  102. data/test/cases/invalid_date_test.rb +32 -32
  103. data/test/cases/invertible_migration_test.rb +295 -295
  104. data/test/cases/json_serialization_test.rb +302 -302
  105. data/test/cases/locking_test.rb +477 -477
  106. data/test/cases/log_subscriber_test.rb +136 -136
  107. data/test/cases/migration/change_schema_test - Copy.rb +448 -448
  108. data/test/cases/migration/change_schema_test.rb +512 -472
  109. data/test/cases/migration/change_table_test.rb +224 -224
  110. data/test/cases/migration/column_attributes_test.rb +192 -192
  111. data/test/cases/migration/column_positioning_test.rb +56 -56
  112. data/test/cases/migration/columns_test.rb +304 -304
  113. data/test/cases/migration/command_recorder_test.rb +305 -305
  114. data/test/cases/migration/create_join_table_test.rb +148 -148
  115. data/test/cases/migration/foreign_key_test - Changed.rb +325 -325
  116. data/test/cases/migration/foreign_key_test.rb +328 -360
  117. data/test/cases/migration/helper.rb +39 -39
  118. data/test/cases/migration/index_test.rb +216 -216
  119. data/test/cases/migration/logger_test.rb +36 -36
  120. data/test/cases/migration/pending_migrations_test.rb +53 -53
  121. data/test/cases/migration/references_foreign_key_test.rb +169 -214
  122. data/test/cases/migration/references_index_test.rb +101 -101
  123. data/test/cases/migration/references_statements_test.rb +116 -116
  124. data/test/cases/migration/rename_table_test.rb +93 -93
  125. data/test/cases/migration/table_and_index_test.rb +24 -24
  126. data/test/cases/migration_test.rb +959 -959
  127. data/test/cases/migrator_test.rb +388 -388
  128. data/test/cases/mixin_test.rb +70 -70
  129. data/test/cases/modules_test.rb +173 -173
  130. data/test/cases/multiparameter_attributes_test.rb +350 -350
  131. data/test/cases/multiple_db_test.rb +115 -115
  132. data/test/cases/nested_attributes_test.rb +1070 -1057
  133. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  134. data/test/cases/persistence_test.rb +909 -909
  135. data/test/cases/pooled_connections_test.rb +81 -81
  136. data/test/cases/primary_keys_test.rb +237 -237
  137. data/test/cases/query_cache_test.rb +326 -326
  138. data/test/cases/quoting_test.rb +156 -156
  139. data/test/cases/readonly_test.rb +118 -118
  140. data/test/cases/reaper_test.rb +85 -85
  141. data/test/cases/reflection_test.rb +463 -454
  142. data/test/cases/relation/delegation_test.rb +68 -68
  143. data/test/cases/relation/merging_test.rb +161 -161
  144. data/test/cases/relation/mutation_test.rb +165 -165
  145. data/test/cases/relation/predicate_builder_test.rb +14 -14
  146. data/test/cases/relation/where_chain_test.rb +181 -181
  147. data/test/cases/relation/where_test.rb +300 -300
  148. data/test/cases/relation/where_test2.rb +36 -36
  149. data/test/cases/relation_test.rb +319 -297
  150. data/test/cases/relations_test.rb +1815 -1815
  151. data/test/cases/reload_models_test.rb +22 -22
  152. data/test/cases/result_test.rb +80 -80
  153. data/test/cases/sanitize_test.rb +83 -83
  154. data/test/cases/schema_dumper_test.rb +463 -463
  155. data/test/cases/scoping/default_scoping_test.rb +454 -454
  156. data/test/cases/scoping/named_scoping_test.rb +524 -524
  157. data/test/cases/scoping/relation_scoping_test.rb +357 -357
  158. data/test/cases/serialization_test.rb +104 -104
  159. data/test/cases/serialized_attribute_test.rb +277 -277
  160. data/test/cases/statement_cache_test.rb +98 -98
  161. data/test/cases/store_test.rb +194 -194
  162. data/test/cases/tasks/database_tasks_test.rb +398 -396
  163. data/test/cases/tasks/mysql_rake_test.rb +324 -311
  164. data/test/cases/tasks/postgresql_rake_test.rb +250 -245
  165. data/test/cases/tasks/sqlite_rake_test.rb +193 -193
  166. data/test/cases/test_case.rb +123 -123
  167. data/test/cases/timestamp_test.rb +467 -468
  168. data/test/cases/transaction_callbacks_test.rb +452 -452
  169. data/test/cases/transaction_isolation_test.rb +106 -106
  170. data/test/cases/transactions_test.rb +817 -817
  171. data/test/cases/type/decimal_test.rb +56 -51
  172. data/test/cases/type/integer_test.rb +121 -121
  173. data/test/cases/type/string_test.rb +36 -36
  174. data/test/cases/type/type_map_test.rb +177 -177
  175. data/test/cases/type/unsigned_integer_test.rb +18 -18
  176. data/test/cases/types_test.rb +141 -141
  177. data/test/cases/unconnected_test.rb +33 -33
  178. data/test/cases/validations/association_validation_test.rb +86 -86
  179. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  180. data/test/cases/validations/i18n_validation_test.rb +90 -90
  181. data/test/cases/validations/length_validation_test.rb +47 -47
  182. data/test/cases/validations/presence_validation_test.rb +68 -68
  183. data/test/cases/validations/uniqueness_validation_test.rb +457 -434
  184. data/test/cases/validations_repair_helper.rb +23 -23
  185. data/test/cases/validations_test.rb +165 -165
  186. data/test/cases/view_test.rb +119 -113
  187. data/test/cases/xml_serialization_test.rb +457 -457
  188. data/test/cases/yaml_serialization_test.rb +126 -86
  189. data/test/config.rb +5 -5
  190. data/test/config.yml +154 -154
  191. data/test/connections/native_ibm_db/connection.rb +43 -43
  192. data/test/fixtures/accounts.yml +29 -29
  193. data/test/fixtures/admin/accounts.yml +2 -2
  194. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  195. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  196. data/test/fixtures/admin/users.yml +10 -10
  197. data/test/fixtures/author_addresses.yml +17 -17
  198. data/test/fixtures/author_favorites.yml +3 -3
  199. data/test/fixtures/authors.yml +23 -23
  200. data/test/fixtures/binaries.yml +133 -133
  201. data/test/fixtures/books.yml +11 -11
  202. data/test/fixtures/bulbs.yml +5 -5
  203. data/test/fixtures/cars.yml +9 -9
  204. data/test/fixtures/categories.yml +19 -19
  205. data/test/fixtures/categories/special_categories.yml +9 -9
  206. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  207. data/test/fixtures/categories_ordered.yml +7 -7
  208. data/test/fixtures/categories_posts.yml +31 -31
  209. data/test/fixtures/categorizations.yml +23 -23
  210. data/test/fixtures/clubs.yml +8 -8
  211. data/test/fixtures/collections.yml +3 -3
  212. data/test/fixtures/colleges.yml +3 -3
  213. data/test/fixtures/comments.yml +65 -65
  214. data/test/fixtures/companies.yml +67 -67
  215. data/test/fixtures/computers.yml +10 -10
  216. data/test/fixtures/courses.yml +8 -8
  217. data/test/fixtures/customers.yml +25 -25
  218. data/test/fixtures/dashboards.yml +6 -6
  219. data/test/fixtures/developers.yml +21 -21
  220. data/test/fixtures/developers_projects.yml +16 -16
  221. data/test/fixtures/dog_lovers.yml +7 -7
  222. data/test/fixtures/dogs.yml +4 -4
  223. data/test/fixtures/doubloons.yml +3 -3
  224. data/test/fixtures/edges.yml +5 -5
  225. data/test/fixtures/entrants.yml +14 -14
  226. data/test/fixtures/essays.yml +6 -6
  227. data/test/fixtures/faces.yml +11 -11
  228. data/test/fixtures/fk_test_has_fk.yml +3 -3
  229. data/test/fixtures/fk_test_has_pk.yml +1 -1
  230. data/test/fixtures/friendships.yml +4 -4
  231. data/test/fixtures/funny_jokes.yml +10 -10
  232. data/test/fixtures/interests.yml +33 -33
  233. data/test/fixtures/items.yml +3 -3
  234. data/test/fixtures/jobs.yml +7 -7
  235. data/test/fixtures/legacy_things.yml +3 -3
  236. data/test/fixtures/mateys.yml +4 -4
  237. data/test/fixtures/member_details.yml +8 -8
  238. data/test/fixtures/member_types.yml +6 -6
  239. data/test/fixtures/members.yml +11 -11
  240. data/test/fixtures/memberships.yml +34 -34
  241. data/test/fixtures/men.yml +5 -5
  242. data/test/fixtures/minimalistics.yml +2 -2
  243. data/test/fixtures/minivans.yml +5 -5
  244. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  245. data/test/fixtures/mixins.yml +29 -29
  246. data/test/fixtures/movies.yml +7 -7
  247. data/test/fixtures/naked/csv/accounts.csv +1 -1
  248. data/test/fixtures/naked/yml/accounts.yml +1 -1
  249. data/test/fixtures/naked/yml/companies.yml +1 -1
  250. data/test/fixtures/naked/yml/courses.yml +1 -1
  251. data/test/fixtures/organizations.yml +5 -5
  252. data/test/fixtures/other_topics.yml +42 -42
  253. data/test/fixtures/owners.yml +9 -9
  254. data/test/fixtures/parrots.yml +27 -27
  255. data/test/fixtures/parrots_pirates.yml +7 -7
  256. data/test/fixtures/people.yml +24 -24
  257. data/test/fixtures/peoples_treasures.yml +3 -3
  258. data/test/fixtures/pets.yml +19 -19
  259. data/test/fixtures/pirates.yml +12 -12
  260. data/test/fixtures/posts.yml +80 -80
  261. data/test/fixtures/price_estimates.yml +7 -7
  262. data/test/fixtures/products.yml +4 -4
  263. data/test/fixtures/projects.yml +7 -7
  264. data/test/fixtures/randomly_named_a9.yml +7 -7
  265. data/test/fixtures/ratings.yml +14 -14
  266. data/test/fixtures/readers.yml +11 -11
  267. data/test/fixtures/references.yml +17 -17
  268. data/test/fixtures/reserved_words/distinct.yml +5 -5
  269. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  270. data/test/fixtures/reserved_words/group.yml +14 -14
  271. data/test/fixtures/reserved_words/select.yml +8 -8
  272. data/test/fixtures/reserved_words/values.yml +7 -7
  273. data/test/fixtures/ships.yml +6 -6
  274. data/test/fixtures/speedometers.yml +8 -8
  275. data/test/fixtures/sponsors.yml +12 -12
  276. data/test/fixtures/string_key_objects.yml +7 -7
  277. data/test/fixtures/subscribers.yml +10 -10
  278. data/test/fixtures/subscriptions.yml +12 -12
  279. data/test/fixtures/taggings.yml +78 -78
  280. data/test/fixtures/tags.yml +11 -11
  281. data/test/fixtures/tasks.yml +7 -7
  282. data/test/fixtures/teapots.yml +3 -3
  283. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  284. data/test/fixtures/to_be_linked/users.yml +10 -10
  285. data/test/fixtures/topics.yml +49 -49
  286. data/test/fixtures/toys.yml +14 -14
  287. data/test/fixtures/traffic_lights.yml +9 -9
  288. data/test/fixtures/treasures.yml +10 -10
  289. data/test/fixtures/uuid_children.yml +3 -3
  290. data/test/fixtures/uuid_parents.yml +2 -2
  291. data/test/fixtures/variants.yml +4 -4
  292. data/test/fixtures/vegetables.yml +19 -19
  293. data/test/fixtures/vertices.yml +3 -3
  294. data/test/fixtures/warehouse_things.yml +2 -2
  295. data/test/fixtures/zines.yml +5 -5
  296. data/test/ibm_db_test.rb +24 -24
  297. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  298. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  299. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  300. data/test/migrations/missing/1000_people_have_middle_names.rb +8 -8
  301. data/test/migrations/missing/1_people_have_last_names.rb +8 -8
  302. data/test/migrations/missing/3_we_need_reminders.rb +11 -11
  303. data/test/migrations/missing/4_innocent_jointable.rb +11 -11
  304. data/test/migrations/rename/1_we_need_things.rb +10 -10
  305. data/test/migrations/rename/2_rename_things.rb +8 -8
  306. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  307. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  308. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  309. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  310. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  311. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  312. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  313. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  314. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  315. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  316. data/test/migrations/valid/2_we_need_reminders.rb +11 -11
  317. data/test/migrations/valid/3_innocent_jointable.rb +11 -11
  318. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  319. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +11 -11
  320. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +11 -11
  321. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  322. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  323. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  324. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  325. data/test/models/admin.rb +4 -4
  326. data/test/models/admin/account.rb +2 -2
  327. data/test/models/admin/randomly_named_c1.rb +3 -3
  328. data/test/models/admin/user.rb +40 -40
  329. data/test/models/aircraft.rb +4 -4
  330. data/test/models/arunit2_model.rb +3 -3
  331. data/test/models/author.rb +212 -212
  332. data/test/models/auto_id.rb +4 -4
  333. data/test/models/autoloadable/extra_firm.rb +2 -2
  334. data/test/models/binary.rb +1 -1
  335. data/test/models/bird.rb +12 -12
  336. data/test/models/book.rb +18 -18
  337. data/test/models/boolean.rb +2 -2
  338. data/test/models/bulb.rb +51 -51
  339. data/test/models/cake_designer.rb +3 -3
  340. data/test/models/car.rb +26 -26
  341. data/test/models/carrier.rb +2 -2
  342. data/test/models/categorization.rb +19 -19
  343. data/test/models/category.rb +35 -35
  344. data/test/models/chef.rb +7 -3
  345. data/test/models/citation.rb +3 -3
  346. data/test/models/club.rb +23 -23
  347. data/test/models/college.rb +10 -10
  348. data/test/models/column.rb +3 -3
  349. data/test/models/column_name.rb +3 -3
  350. data/test/models/comment.rb +64 -64
  351. data/test/models/company.rb +228 -225
  352. data/test/models/company_in_module.rb +98 -98
  353. data/test/models/computer.rb +3 -3
  354. data/test/models/contact.rb +41 -41
  355. data/test/models/contract.rb +20 -20
  356. data/test/models/country.rb +7 -7
  357. data/test/models/course.rb +6 -6
  358. data/test/models/customer.rb +77 -77
  359. data/test/models/customer_carrier.rb +14 -14
  360. data/test/models/dashboard.rb +3 -3
  361. data/test/models/default.rb +2 -2
  362. data/test/models/department.rb +4 -4
  363. data/test/models/developer.rb +255 -252
  364. data/test/models/dog.rb +5 -5
  365. data/test/models/dog_lover.rb +5 -5
  366. data/test/models/doubloon.rb +12 -12
  367. data/test/models/drink_designer.rb +3 -3
  368. data/test/models/edge.rb +5 -5
  369. data/test/models/electron.rb +5 -5
  370. data/test/models/engine.rb +4 -4
  371. data/test/models/entrant.rb +3 -3
  372. data/test/models/essay.rb +5 -5
  373. data/test/models/event.rb +2 -2
  374. data/test/models/eye.rb +37 -37
  375. data/test/models/face.rb +9 -9
  376. data/test/models/friendship.rb +6 -6
  377. data/test/models/guid.rb +1 -1
  378. data/test/models/hotel.rb +9 -6
  379. data/test/models/image.rb +3 -3
  380. data/test/models/interest.rb +5 -5
  381. data/test/models/invoice.rb +4 -4
  382. data/test/models/item.rb +7 -7
  383. data/test/models/job.rb +7 -7
  384. data/test/models/joke.rb +7 -7
  385. data/test/models/keyboard.rb +3 -3
  386. data/test/models/legacy_thing.rb +3 -3
  387. data/test/models/lesson.rb +11 -11
  388. data/test/models/line_item.rb +3 -3
  389. data/test/models/liquid.rb +4 -4
  390. data/test/models/man.rb +11 -11
  391. data/test/models/matey.rb +4 -4
  392. data/test/models/member.rb +41 -41
  393. data/test/models/member_detail.rb +7 -7
  394. data/test/models/member_type.rb +3 -3
  395. data/test/models/membership.rb +35 -35
  396. data/test/models/minimalistic.rb +2 -2
  397. data/test/models/minivan.rb +9 -9
  398. data/test/models/mixed_case_monkey.rb +3 -3
  399. data/test/models/molecule.rb +6 -6
  400. data/test/models/movie.rb +5 -5
  401. data/test/models/order.rb +4 -4
  402. data/test/models/organization.rb +14 -14
  403. data/test/models/owner.rb +34 -34
  404. data/test/models/parrot.rb +29 -29
  405. data/test/models/person.rb +143 -143
  406. data/test/models/personal_legacy_thing.rb +4 -4
  407. data/test/models/pet.rb +15 -15
  408. data/test/models/pirate.rb +92 -92
  409. data/test/models/possession.rb +3 -3
  410. data/test/models/post.rb +264 -264
  411. data/test/models/price_estimate.rb +4 -4
  412. data/test/models/professor.rb +5 -5
  413. data/test/models/project.rb +31 -29
  414. data/test/models/publisher.rb +2 -2
  415. data/test/models/publisher/article.rb +4 -4
  416. data/test/models/publisher/magazine.rb +3 -3
  417. data/test/models/randomly_named_c1.rb +3 -3
  418. data/test/models/rating.rb +4 -4
  419. data/test/models/reader.rb +23 -23
  420. data/test/models/record.rb +2 -2
  421. data/test/models/reference.rb +22 -22
  422. data/test/models/reply.rb +61 -61
  423. data/test/models/ship.rb +33 -33
  424. data/test/models/ship_part.rb +7 -7
  425. data/test/models/shop.rb +17 -17
  426. data/test/models/shop_account.rb +6 -6
  427. data/test/models/speedometer.rb +6 -6
  428. data/test/models/sponsor.rb +7 -7
  429. data/test/models/string_key_object.rb +3 -3
  430. data/test/models/student.rb +4 -4
  431. data/test/models/subject.rb +16 -16
  432. data/test/models/subscriber.rb +8 -8
  433. data/test/models/subscription.rb +4 -4
  434. data/test/models/tag.rb +7 -7
  435. data/test/models/tagging.rb +13 -13
  436. data/test/models/task.rb +5 -5
  437. data/test/models/topic.rb +124 -124
  438. data/test/models/toy.rb +6 -6
  439. data/test/models/traffic_light.rb +4 -4
  440. data/test/models/treasure.rb +14 -14
  441. data/test/models/treaty.rb +7 -7
  442. data/test/models/tyre.rb +11 -11
  443. data/test/models/uuid_child.rb +3 -3
  444. data/test/models/uuid_parent.rb +3 -3
  445. data/test/models/vegetables.rb +24 -24
  446. data/test/models/vehicle.rb +6 -6
  447. data/test/models/vertex.rb +9 -9
  448. data/test/models/warehouse_thing.rb +5 -5
  449. data/test/models/wheel.rb +3 -3
  450. data/test/models/without_table.rb +3 -3
  451. data/test/models/zine.rb +3 -3
  452. data/test/schema/mysql2_specific_schema.rb +58 -58
  453. data/test/schema/mysql_specific_schema.rb +70 -70
  454. data/test/schema/oracle_specific_schema.rb +43 -43
  455. data/test/schema/postgresql_specific_schema.rb +202 -202
  456. data/test/schema/schema.rb +952 -938
  457. data/test/schema/sqlite_specific_schema.rb +21 -21
  458. data/test/support/config.rb +43 -43
  459. data/test/support/connection.rb +22 -22
  460. data/test/support/connection_helper.rb +14 -14
  461. data/test/support/ddl_helper.rb +8 -8
  462. data/test/support/schema_dumping_helper.rb +20 -20
  463. metadata +2 -2
@@ -1,21 +1,21 @@
1
- require 'cases/helper'
2
- require 'models/post'
3
- require 'models/author'
4
-
5
- module ActiveRecord
6
- module Associations
7
- class AssociationScopeTest < ActiveRecord::TestCase
8
- test 'does not duplicate conditions' do
9
- scope = AssociationScope.scope(Author.new.association(:welcome_posts),
10
- Author.connection)
11
- wheres = scope.where_values.map(&:right)
12
- binds = scope.bind_values.map(&:last)
13
- wheres = scope.where_values.map(&:right).reject { |node|
14
- Arel::Nodes::BindParam === node
15
- }
16
- assert_equal wheres.uniq, wheres
17
- assert_equal binds.uniq, binds
18
- end
19
- end
20
- end
21
- end
1
+ require 'cases/helper'
2
+ require 'models/post'
3
+ require 'models/author'
4
+
5
+ module ActiveRecord
6
+ module Associations
7
+ class AssociationScopeTest < ActiveRecord::TestCase
8
+ test 'does not duplicate conditions' do
9
+ scope = AssociationScope.scope(Author.new.association(:welcome_posts),
10
+ Author.connection)
11
+ wheres = scope.where_values.map(&:right)
12
+ binds = scope.bind_values.map(&:last)
13
+ wheres = scope.where_values.map(&:right).reject { |node|
14
+ Arel::Nodes::BindParam === node
15
+ }
16
+ assert_equal wheres.uniq, wheres
17
+ assert_equal binds.uniq, binds
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,1029 +1,1029 @@
1
- require 'cases/helper'
2
- require 'models/developer'
3
- require 'models/computer'
4
- require 'models/project'
5
- require 'models/company'
6
- require 'models/topic'
7
- require 'models/reply'
8
- require 'models/computer'
9
- require 'models/post'
10
- require 'models/author'
11
- require 'models/tag'
12
- require 'models/tagging'
13
- require 'models/comment'
14
- require 'models/sponsor'
15
- require 'models/member'
16
- require 'models/essay'
17
- require 'models/toy'
18
- require 'models/invoice'
19
- require 'models/line_item'
20
- require 'models/column'
21
- require 'models/record'
22
- require 'models/admin'
23
- require 'models/admin/user'
24
- require 'models/ship'
25
- require 'models/treasure'
26
- require 'models/parrot'
27
-
28
- class BelongsToAssociationsTest < ActiveRecord::TestCase
29
- fixtures :accounts, :companies, :developers, :projects, :topics,
30
- :developers_projects, :computers, :authors, :author_addresses,
31
- :posts, :tags, :taggings, :comments, :sponsors, :members
32
-
33
- def test_belongs_to
34
- firm = Client.find(3).firm
35
- assert_not_nil firm
36
- assert_equal companies(:first_firm).name, firm.name
37
- end
38
-
39
- def test_belongs_to_does_not_use_order_by
40
- ActiveRecord::SQLCounter.clear_log
41
- Client.find(3).firm
42
- ensure
43
- assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query'
44
- end
45
-
46
- def test_belongs_to_with_primary_key
47
- client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
48
- assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
49
- end
50
-
51
- def test_belongs_to_with_primary_key_joins_on_correct_column
52
- sql = Client.joins(:firm_with_primary_key).to_sql
53
- if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
54
- assert_no_match(/`firm_with_primary_keys_companies`\.`id`/, sql)
55
- assert_match(/`firm_with_primary_keys_companies`\.`name`/, sql)
56
- elsif current_adapter?(:OracleAdapter)
57
- # on Oracle aliases are truncated to 30 characters and are quoted in uppercase
58
- assert_no_match(/"firm_with_primary_keys_compani"\."id"/i, sql)
59
- assert_match(/"firm_with_primary_keys_compani"\."name"/i, sql)
60
- elsif current_adapter?(:IBM_DBAdapter)
61
- # Quoting of column names is not necessary for IBM_DB
62
- assert_no_match(/firm_with_primary_keys_companies\.id/i, sql)
63
- assert_match(/firm_with_primary_keys_companies\.name/i, sql)
64
- else
65
- assert_no_match(/"firm_with_primary_keys_companies"\."id"/, sql)
66
- assert_match(/"firm_with_primary_keys_companies"\."name"/, sql)
67
- end
68
- end
69
-
70
- def test_default_scope_on_relations_is_not_cached
71
- counter = 0
72
-
73
- comments = Class.new(ActiveRecord::Base) {
74
- self.table_name = 'comments'
75
- self.inheritance_column = 'not_there'
76
-
77
- posts = Class.new(ActiveRecord::Base) {
78
- self.table_name = 'posts'
79
- self.inheritance_column = 'not_there'
80
-
81
- default_scope -> {
82
- counter += 1
83
- where("id = :inc", :inc => counter)
84
- }
85
-
86
- has_many :comments, :anonymous_class => comments
87
- }
88
- belongs_to :post, :anonymous_class => posts, :inverse_of => false
89
- }
90
-
91
- assert_equal 0, counter
92
- comment = comments.first
93
- assert_equal 0, counter
94
- sql = capture_sql { comment.post }
95
- comment.reload
96
- assert_not_equal sql, capture_sql { comment.post }
97
- end
98
-
99
- def test_proxy_assignment
100
- account = Account.find(1)
101
- assert_nothing_raised { account.firm = account.firm }
102
- end
103
-
104
- def test_type_mismatch
105
- assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
106
- assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
107
- end
108
-
109
- def test_raises_type_mismatch_with_namespaced_class
110
- assert_nil defined?(Region), "This test requires that there is no top-level Region class"
111
-
112
- ActiveRecord::Base.connection.instance_eval do
113
- create_table(:admin_regions) { |t| t.string :name }
114
- add_column :admin_users, :region_id, :integer
115
- end
116
- Admin.const_set "RegionalUser", Class.new(Admin::User) { belongs_to(:region) }
117
- Admin.const_set "Region", Class.new(ActiveRecord::Base)
118
-
119
- e = assert_raise(ActiveRecord::AssociationTypeMismatch) {
120
- Admin::RegionalUser.new(region: 'wrong value')
121
- }
122
- assert_match(/^Region\([^)]+\) expected, got String\([^)]+\)$/, e.message)
123
- ensure
124
- Admin.send :remove_const, "Region" if Admin.const_defined?("Region")
125
- Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser")
126
-
127
- ActiveRecord::Base.connection.instance_eval do
128
- remove_column :admin_users, :region_id if column_exists?(:admin_users, :region_id)
129
- drop_table :admin_regions, if_exists: true
130
- end
131
- end
132
-
133
- def test_natural_assignment
134
- apple = Firm.create("name" => "Apple")
135
- citibank = Account.create("credit_limit" => 10)
136
- citibank.firm = apple
137
- assert_equal apple.id, citibank.firm_id
138
- end
139
-
140
- def test_id_assignment
141
- apple = Firm.create("name" => "Apple")
142
- citibank = Account.create("credit_limit" => 10)
143
- citibank.firm_id = apple
144
- assert_nil citibank.firm_id
145
- end
146
-
147
- def test_natural_assignment_with_primary_key
148
- apple = Firm.create("name" => "Apple")
149
- citibank = Client.create("name" => "Primary key client")
150
- citibank.firm_with_primary_key = apple
151
- assert_equal apple.name, citibank.firm_name
152
- end
153
-
154
- def test_eager_loading_with_primary_key
155
- Firm.create("name" => "Apple")
156
- Client.create("name" => "Citibank", :firm_name => "Apple")
157
- citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key).first
158
- assert citibank_result.association(:firm_with_primary_key).loaded?
159
- end
160
-
161
- def test_eager_loading_with_primary_key_as_symbol
162
- Firm.create("name" => "Apple")
163
- Client.create("name" => "Citibank", :firm_name => "Apple")
164
- citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key_symbols).first
165
- assert citibank_result.association(:firm_with_primary_key_symbols).loaded?
166
- end
167
-
168
- def test_creating_the_belonging_object
169
- citibank = Account.create("credit_limit" => 10)
170
- apple = citibank.create_firm("name" => "Apple")
171
- assert_equal apple, citibank.firm
172
- citibank.save
173
- citibank.reload
174
- assert_equal apple, citibank.firm
175
- end
176
-
177
- def test_creating_the_belonging_object_with_primary_key
178
- client = Client.create(:name => "Primary key client")
179
- apple = client.create_firm_with_primary_key("name" => "Apple")
180
- assert_equal apple, client.firm_with_primary_key
181
- client.save
182
- client.reload
183
- assert_equal apple, client.firm_with_primary_key
184
- end
185
-
186
- def test_building_the_belonging_object
187
- citibank = Account.create("credit_limit" => 10)
188
- apple = citibank.build_firm("name" => "Apple")
189
- citibank.save
190
- assert_equal apple.id, citibank.firm_id
191
- end
192
-
193
- def test_building_the_belonging_object_with_implicit_sti_base_class
194
- account = Account.new
195
- company = account.build_firm
196
- assert_kind_of Company, company, "Expected #{company.class} to be a Company"
197
- end
198
-
199
- def test_building_the_belonging_object_with_explicit_sti_base_class
200
- account = Account.new
201
- company = account.build_firm(:type => "Company")
202
- assert_kind_of Company, company, "Expected #{company.class} to be a Company"
203
- end
204
-
205
- def test_building_the_belonging_object_with_sti_subclass
206
- account = Account.new
207
- company = account.build_firm(:type => "Firm")
208
- assert_kind_of Firm, company, "Expected #{company.class} to be a Firm"
209
- end
210
-
211
- def test_building_the_belonging_object_with_an_invalid_type
212
- account = Account.new
213
- assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "InvalidType") }
214
- end
215
-
216
- def test_building_the_belonging_object_with_an_unrelated_type
217
- account = Account.new
218
- assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "Account") }
219
- end
220
-
221
- def test_building_the_belonging_object_with_primary_key
222
- client = Client.create(:name => "Primary key client")
223
- apple = client.build_firm_with_primary_key("name" => "Apple")
224
- client.save
225
- assert_equal apple.name, client.firm_name
226
- end
227
-
228
- def test_create!
229
- client = Client.create!(:name => "Jimmy")
230
- account = client.create_account!(:credit_limit => 10)
231
- assert_equal account, client.account
232
- assert account.persisted?
233
- client.save
234
- client.reload
235
- assert_equal account, client.account
236
- end
237
-
238
- def test_failing_create!
239
- client = Client.create!(:name => "Jimmy")
240
- assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
241
- assert_not_nil client.account
242
- assert client.account.new_record?
243
- end
244
-
245
- def test_natural_assignment_to_nil
246
- client = Client.find(3)
247
- client.firm = nil
248
- client.save
249
- assert_nil client.firm(true)
250
- assert_nil client.client_of
251
- end
252
-
253
- def test_natural_assignment_to_nil_with_primary_key
254
- client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
255
- client.firm_with_primary_key = nil
256
- client.save
257
- assert_nil client.firm_with_primary_key(true)
258
- assert_nil client.client_of
259
- end
260
-
261
- def test_with_different_class_name
262
- assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
263
- assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
264
- end
265
-
266
- def test_with_condition
267
- assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
268
- assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
269
- end
270
-
271
- def test_polymorphic_association_class
272
- sponsor = Sponsor.new
273
- assert_nil sponsor.association(:sponsorable).send(:klass)
274
- assert_nil sponsor.sponsorable(force_reload: true)
275
-
276
- sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL
277
- assert_nil sponsor.association(:sponsorable).send(:klass)
278
- assert_nil sponsor.sponsorable(force_reload: true)
279
-
280
- sponsor.sponsorable = Member.new :name => "Bert"
281
- assert_equal Member, sponsor.association(:sponsorable).send(:klass)
282
- assert_equal "members", sponsor.association(:sponsorable).aliased_table_name
283
- end
284
-
285
- def test_with_polymorphic_and_condition
286
- sponsor = Sponsor.create
287
- member = Member.create :name => "Bert"
288
- sponsor.sponsorable = member
289
-
290
- assert_equal member, sponsor.sponsorable
291
- assert_nil sponsor.sponsorable_with_conditions
292
- end
293
-
294
- def test_with_select
295
- assert_equal 1, Company.find(2).firm_with_select.attributes.size
296
- assert_equal 1, Company.all.merge!(:includes => :firm_with_select ).find(2).firm_with_select.attributes.size
297
- end
298
-
299
- def test_belongs_to_without_counter_cache_option
300
- # Ship has a conventionally named `treasures_count` column, but the counter_cache
301
- # option is not given on the association.
302
- ship = Ship.create(name: 'Countless')
303
-
304
- assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
305
- treasure = Treasure.new(name: 'Gold', ship: ship)
306
- treasure.save
307
- end
308
-
309
- assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
310
- treasure = ship.treasures.first
311
- treasure.destroy
312
- end
313
- end
314
-
315
- def test_belongs_to_counter
316
- debate = Topic.create("title" => "debate")
317
- assert_equal 0, debate.read_attribute("replies_count"), "No replies yet"
318
-
319
- trash = debate.replies.create("title" => "blah!", "content" => "world around!")
320
- assert_equal 1, Topic.find(debate.id).read_attribute("replies_count"), "First reply created"
321
-
322
- trash.destroy
323
- assert_equal 0, Topic.find(debate.id).read_attribute("replies_count"), "First reply deleted"
324
- end
325
-
326
- def test_belongs_to_counter_with_assigning_nil
327
- post = Post.find(1)
328
- comment = Comment.find(1)
329
-
330
- assert_equal post.id, comment.post_id
331
- assert_equal 2, Post.find(post.id).comments.size
332
-
333
- comment.post = nil
334
-
335
- assert_equal 1, Post.find(post.id).comments.size
336
- end
337
-
338
- def test_belongs_to_with_primary_key_counter
339
- debate = Topic.create("title" => "debate")
340
- debate2 = Topic.create("title" => "debate2")
341
- reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
342
-
343
- assert_equal 1, debate.reload.replies_count
344
- assert_equal 0, debate2.reload.replies_count
345
-
346
- reply.topic_with_primary_key = debate2
347
-
348
- assert_equal 0, debate.reload.replies_count
349
- assert_equal 1, debate2.reload.replies_count
350
-
351
- reply.topic_with_primary_key = nil
352
-
353
- assert_equal 0, debate.reload.replies_count
354
- assert_equal 0, debate2.reload.replies_count
355
- end
356
-
357
- def test_belongs_to_counter_with_reassigning
358
- topic1 = Topic.create("title" => "t1")
359
- topic2 = Topic.create("title" => "t2")
360
- reply1 = Reply.new("title" => "r1", "content" => "r1")
361
- reply1.topic = topic1
362
-
363
- assert reply1.save
364
- assert_equal 1, Topic.find(topic1.id).replies.size
365
- assert_equal 0, Topic.find(topic2.id).replies.size
366
-
367
- reply1.topic = Topic.find(topic2.id)
368
-
369
- assert_no_queries do
370
- reply1.topic = topic2
371
- end
372
-
373
- assert reply1.save
374
- assert_equal 0, Topic.find(topic1.id).replies.size
375
- assert_equal 1, Topic.find(topic2.id).replies.size
376
-
377
- reply1.topic = nil
378
-
379
- assert_equal 0, Topic.find(topic1.id).replies.size
380
- assert_equal 0, Topic.find(topic2.id).replies.size
381
-
382
- reply1.topic = topic1
383
-
384
- assert_equal 1, Topic.find(topic1.id).replies.size
385
- assert_equal 0, Topic.find(topic2.id).replies.size
386
-
387
- reply1.destroy
388
-
389
- assert_equal 0, Topic.find(topic1.id).replies.size
390
- assert_equal 0, Topic.find(topic2.id).replies.size
391
- end
392
-
393
- def test_belongs_to_reassign_with_namespaced_models_and_counters
394
- topic1 = Web::Topic.create("title" => "t1")
395
- topic2 = Web::Topic.create("title" => "t2")
396
- reply1 = Web::Reply.new("title" => "r1", "content" => "r1")
397
- reply1.topic = topic1
398
-
399
- assert reply1.save
400
- assert_equal 1, Web::Topic.find(topic1.id).replies.size
401
- assert_equal 0, Web::Topic.find(topic2.id).replies.size
402
-
403
- reply1.topic = Web::Topic.find(topic2.id)
404
-
405
- assert reply1.save
406
- assert_equal 0, Web::Topic.find(topic1.id).replies.size
407
- assert_equal 1, Web::Topic.find(topic2.id).replies.size
408
- end
409
-
410
- def test_belongs_to_counter_after_save
411
- topic = Topic.create!(:title => "monday night")
412
- topic.replies.create!(:title => "re: monday night", :content => "football")
413
- assert_equal 1, Topic.find(topic.id)[:replies_count]
414
-
415
- topic.save!
416
- assert_equal 1, Topic.find(topic.id)[:replies_count]
417
- end
418
-
419
- def test_belongs_to_with_touch_option_on_touch
420
- line_item = LineItem.create!
421
- Invoice.create!(line_items: [line_item])
422
-
423
- assert_queries(1) { line_item.touch }
424
- end
425
-
426
- def test_belongs_to_with_touch_option_on_touch_without_updated_at_attributes
427
- assert_not LineItem.column_names.include?("updated_at")
428
-
429
- line_item = LineItem.create!
430
- invoice = Invoice.create!(line_items: [line_item])
431
- initial = invoice.updated_at
432
- line_item.touch
433
-
434
- assert_not_equal initial, invoice.reload.updated_at
435
- end
436
-
437
- def test_belongs_to_with_touch_option_on_touch_and_removed_parent
438
- line_item = LineItem.create!
439
- Invoice.create!(line_items: [line_item])
440
-
441
- line_item.invoice = nil
442
-
443
- assert_queries(2) { line_item.touch }
444
- end
445
-
446
- def test_belongs_to_with_touch_option_on_update
447
- line_item = LineItem.create!
448
- Invoice.create!(line_items: [line_item])
449
-
450
- assert_queries(2) { line_item.update amount: 10 }
451
- end
452
-
453
- def test_belongs_to_with_touch_option_on_empty_update
454
- line_item = LineItem.create!
455
- Invoice.create!(line_items: [line_item])
456
-
457
- assert_queries(0) { line_item.save }
458
- end
459
-
460
- def test_belongs_to_with_touch_option_on_destroy
461
- line_item = LineItem.create!
462
- Invoice.create!(line_items: [line_item])
463
-
464
- assert_queries(2) { line_item.destroy }
465
- end
466
-
467
- def test_belongs_to_with_touch_option_on_destroy_with_destroyed_parent
468
- line_item = LineItem.create!
469
- invoice = Invoice.create!(line_items: [line_item])
470
- invoice.destroy
471
-
472
- assert_queries(1) { line_item.destroy }
473
- end
474
-
475
- def test_belongs_to_with_touch_option_on_touch_and_reassigned_parent
476
- line_item = LineItem.create!
477
- Invoice.create!(line_items: [line_item])
478
-
479
- line_item.invoice = Invoice.create!
480
-
481
- assert_queries(3) { line_item.touch }
482
- end
483
-
484
- def test_belongs_to_counter_after_update
485
- topic = Topic.create!(title: "37s")
486
- topic.replies.create!(title: "re: 37s", content: "rails")
487
- assert_equal 1, Topic.find(topic.id)[:replies_count]
488
-
489
- topic.update(title: "37signals")
490
- assert_equal 1, Topic.find(topic.id)[:replies_count]
491
- end
492
-
493
- def test_belongs_to_counter_when_update_columns
494
- topic = Topic.create!(:title => "37s")
495
- topic.replies.create!(:title => "re: 37s", :content => "rails")
496
- assert_equal 1, Topic.find(topic.id)[:replies_count]
497
-
498
- topic.update_columns(content: "rails is wonderful")
499
- assert_equal 1, Topic.find(topic.id)[:replies_count]
500
- end
501
-
502
- def test_assignment_before_child_saved
503
- final_cut = Client.new("name" => "Final Cut")
504
- firm = Firm.find(1)
505
- final_cut.firm = firm
506
- assert !final_cut.persisted?
507
- assert final_cut.save
508
- assert final_cut.persisted?
509
- assert firm.persisted?
510
- assert_equal firm, final_cut.firm
511
- assert_equal firm, final_cut.firm(true)
512
- end
513
-
514
- def test_assignment_before_child_saved_with_primary_key
515
- final_cut = Client.new("name" => "Final Cut")
516
- firm = Firm.find(1)
517
- final_cut.firm_with_primary_key = firm
518
- assert !final_cut.persisted?
519
- assert final_cut.save
520
- assert final_cut.persisted?
521
- assert firm.persisted?
522
- assert_equal firm, final_cut.firm_with_primary_key
523
- assert_equal firm, final_cut.firm_with_primary_key(true)
524
- end
525
-
526
- def test_new_record_with_foreign_key_but_no_object
527
- client = Client.new("firm_id" => 1)
528
- # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
529
- assert_equal Firm.all.merge!(:order => "id").first, client.firm_with_basic_id
530
- end
531
-
532
- def test_setting_foreign_key_after_nil_target_loaded
533
- client = Client.new
534
- client.firm_with_basic_id
535
- client.firm_id = 1
536
-
537
- assert_equal companies(:first_firm), client.firm_with_basic_id
538
- end
539
-
540
- def test_polymorphic_setting_foreign_key_after_nil_target_loaded
541
- sponsor = Sponsor.new
542
- sponsor.sponsorable
543
- sponsor.sponsorable_id = 1
544
- sponsor.sponsorable_type = "Member"
545
-
546
- assert_equal members(:groucho), sponsor.sponsorable
547
- end
548
-
549
- def test_dont_find_target_when_foreign_key_is_null
550
- tagging = taggings(:thinking_general)
551
- assert_queries(0) { tagging.super_tag }
552
- end
553
-
554
- def test_field_name_same_as_foreign_key
555
- computer = Computer.find(1)
556
- assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
557
- end
558
-
559
- def test_counter_cache
560
- topic = Topic.create :title => "Zoom-zoom-zoom"
561
- assert_equal 0, topic[:replies_count]
562
-
563
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
564
- reply.topic = topic
565
-
566
- assert_equal 1, topic.reload[:replies_count]
567
- assert_equal 1, topic.replies.size
568
-
569
- topic[:replies_count] = 15
570
- assert_equal 15, topic.replies.size
571
- end
572
-
573
- def test_counter_cache_double_destroy
574
- topic = Topic.create :title => "Zoom-zoom-zoom"
575
-
576
- 5.times do
577
- topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
578
- end
579
-
580
- assert_equal 5, topic.reload[:replies_count]
581
- assert_equal 5, topic.replies.size
582
-
583
- reply = topic.replies.first
584
-
585
- reply.destroy
586
- assert_equal 4, topic.reload[:replies_count]
587
-
588
- reply.destroy
589
- assert_equal 4, topic.reload[:replies_count]
590
- assert_equal 4, topic.replies.size
591
- end
592
-
593
- def test_concurrent_counter_cache_double_destroy
594
- topic = Topic.create :title => "Zoom-zoom-zoom"
595
-
596
- 5.times do
597
- topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
598
- end
599
-
600
- assert_equal 5, topic.reload[:replies_count]
601
- assert_equal 5, topic.replies.size
602
-
603
- reply = topic.replies.first
604
- reply_clone = Reply.find(reply.id)
605
-
606
- reply.destroy
607
- assert_equal 4, topic.reload[:replies_count]
608
-
609
- reply_clone.destroy
610
- assert_equal 4, topic.reload[:replies_count]
611
- assert_equal 4, topic.replies.size
612
- end
613
-
614
- def test_custom_counter_cache
615
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
616
- assert_equal 0, reply[:replies_count]
617
-
618
- silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
619
- silly.reply = reply
620
-
621
- assert_equal 1, reply.reload[:replies_count]
622
- assert_equal 1, reply.replies.size
623
-
624
- reply[:replies_count] = 17
625
- assert_equal 17, reply.replies.size
626
- end
627
-
628
- def test_association_assignment_sticks
629
- post = Post.first
630
-
631
- author1, author2 = Author.all.merge!(:limit => 2).to_a
632
- assert_not_nil author1
633
- assert_not_nil author2
634
-
635
- # make sure the association is loaded
636
- post.author
637
-
638
- # set the association by id, directly
639
- post.author_id = author2.id
640
-
641
- # save and reload
642
- post.save!
643
- post.reload
644
-
645
- # the author id of the post should be the id we set
646
- assert_equal post.author_id, author2.id
647
- end
648
-
649
- def test_cant_save_readonly_association
650
- assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
651
- assert companies(:first_client).readonly_firm.readonly?
652
- end
653
-
654
- def test_test_polymorphic_assignment_foreign_key_type_string
655
- comment = Comment.first
656
- comment.author = Author.first
657
- comment.resource = Member.first
658
- comment.save
659
-
660
- assert_equal Comment.all.to_a,
661
- Comment.includes(:author).to_a
662
-
663
- assert_equal Comment.all.to_a,
664
- Comment.includes(:resource).to_a
665
- end
666
-
667
- def test_polymorphic_assignment_foreign_type_field_updating
668
- # should update when assigning a saved record
669
- sponsor = Sponsor.new
670
- member = Member.create
671
- sponsor.sponsorable = member
672
- assert_equal "Member", sponsor.sponsorable_type
673
-
674
- # should update when assigning a new record
675
- sponsor = Sponsor.new
676
- member = Member.new
677
- sponsor.sponsorable = member
678
- assert_equal "Member", sponsor.sponsorable_type
679
- end
680
-
681
- def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating
682
- # should update when assigning a saved record
683
- essay = Essay.new
684
- writer = Author.create(:name => "David")
685
- essay.writer = writer
686
- assert_equal "Author", essay.writer_type
687
-
688
- # should update when assigning a new record
689
- essay = Essay.new
690
- writer = Author.new
691
- essay.writer = writer
692
- assert_equal "Author", essay.writer_type
693
- end
694
-
695
- def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
696
- sponsor = Sponsor.new
697
- saved_member = Member.create
698
- new_member = Member.new
699
-
700
- sponsor.sponsorable = saved_member
701
- assert_equal saved_member.id, sponsor.sponsorable_id
702
-
703
- sponsor.sponsorable = new_member
704
- assert_nil sponsor.sponsorable_id
705
- end
706
-
707
- def test_assignment_updates_foreign_id_field_for_new_and_saved_records
708
- client = Client.new
709
- saved_firm = Firm.create :name => "Saved"
710
- new_firm = Firm.new
711
-
712
- client.firm = saved_firm
713
- assert_equal saved_firm.id, client.client_of
714
-
715
- client.firm = new_firm
716
- assert_nil client.client_of
717
- end
718
-
719
- def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
720
- essay = Essay.new
721
- saved_writer = Author.create(:name => "David")
722
- new_writer = Author.new
723
-
724
- essay.writer = saved_writer
725
- assert_equal saved_writer.name, essay.writer_id
726
-
727
- essay.writer = new_writer
728
- assert_nil essay.writer_id
729
- end
730
-
731
- def test_polymorphic_assignment_with_nil
732
- essay = Essay.new
733
- assert_nil essay.writer_id
734
- assert_nil essay.writer_type
735
-
736
- essay.writer_id = 1
737
- essay.writer_type = 'Author'
738
-
739
- essay.writer = nil
740
- assert_nil essay.writer_id
741
- assert_nil essay.writer_type
742
- end
743
-
744
- def test_belongs_to_proxy_should_not_respond_to_private_methods
745
- assert_raise(NoMethodError) { companies(:first_firm).private_method }
746
- assert_raise(NoMethodError) { companies(:second_client).firm.private_method }
747
- end
748
-
749
- def test_belongs_to_proxy_should_respond_to_private_methods_via_send
750
- companies(:first_firm).send(:private_method)
751
- companies(:second_client).firm.send(:private_method)
752
- end
753
-
754
- def test_save_of_record_with_loaded_belongs_to
755
- @account = companies(:first_firm).account
756
-
757
- assert_nothing_raised do
758
- Account.find(@account.id).save!
759
- Account.all.merge!(:includes => :firm).find(@account.id).save!
760
- end
761
-
762
- @account.firm.delete
763
-
764
- assert_nothing_raised do
765
- Account.find(@account.id).save!
766
- Account.all.merge!(:includes => :firm).find(@account.id).save!
767
- end
768
- end
769
-
770
- def test_dependent_delete_and_destroy_with_belongs_to
771
- AuthorAddress.destroyed_author_address_ids.clear
772
-
773
- author_address = author_addresses(:david_address)
774
- author_address_extra = author_addresses(:david_address_extra)
775
- assert_equal [], AuthorAddress.destroyed_author_address_ids
776
-
777
- assert_difference "AuthorAddress.count", -2 do
778
- authors(:david).destroy
779
- end
780
-
781
- assert_equal [], AuthorAddress.where(id: [author_address.id, author_address_extra.id])
782
- assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids
783
- end
784
-
785
- def test_belongs_to_invalid_dependent_option_raises_exception
786
- error = assert_raise ArgumentError do
787
- Class.new(Author).belongs_to :special_author_address, :dependent => :nullify
788
- end
789
- assert_equal error.message, 'The :dependent option must be one of [:destroy, :delete], but is :nullify'
790
- end
791
-
792
- def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
793
- new_firm = accounts(:signals37).build_firm(:name => 'Apple')
794
- assert_equal new_firm.name, "Apple"
795
- end
796
-
797
- def test_attributes_are_set_without_error_when_initialized_from_belongs_to_association_with_array_in_where_clause
798
- new_account = Account.where(:credit_limit => [ 50, 60 ]).new
799
- assert_nil new_account.credit_limit
800
- end
801
-
802
- def test_reassigning_the_parent_id_updates_the_object
803
- client = companies(:second_client)
804
-
805
- client.firm
806
- client.firm_with_condition
807
- firm_proxy = client.send(:association_instance_get, :firm)
808
- firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
809
-
810
- assert !firm_proxy.stale_target?
811
- assert !firm_with_condition_proxy.stale_target?
812
- assert_equal companies(:first_firm), client.firm
813
- assert_equal companies(:first_firm), client.firm_with_condition
814
-
815
- client.client_of = companies(:another_firm).id
816
-
817
- assert firm_proxy.stale_target?
818
- assert firm_with_condition_proxy.stale_target?
819
- assert_equal companies(:another_firm), client.firm
820
- assert_equal companies(:another_firm), client.firm_with_condition
821
- end
822
-
823
- def test_polymorphic_reassignment_of_associated_id_updates_the_object
824
- sponsor = sponsors(:moustache_club_sponsor_for_groucho)
825
-
826
- sponsor.sponsorable
827
- proxy = sponsor.send(:association_instance_get, :sponsorable)
828
-
829
- assert !proxy.stale_target?
830
- assert_equal members(:groucho), sponsor.sponsorable
831
-
832
- sponsor.sponsorable_id = members(:some_other_guy).id
833
-
834
- assert proxy.stale_target?
835
- assert_equal members(:some_other_guy), sponsor.sponsorable
836
- end
837
-
838
- def test_polymorphic_reassignment_of_associated_type_updates_the_object
839
- sponsor = sponsors(:moustache_club_sponsor_for_groucho)
840
-
841
- sponsor.sponsorable
842
- proxy = sponsor.send(:association_instance_get, :sponsorable)
843
-
844
- assert !proxy.stale_target?
845
- assert_equal members(:groucho), sponsor.sponsorable
846
-
847
- sponsor.sponsorable_type = 'Firm'
848
-
849
- assert proxy.stale_target?
850
- assert_equal companies(:first_firm), sponsor.sponsorable
851
- end
852
-
853
- def test_reloading_association_with_key_change
854
- client = companies(:second_client)
855
- firm = client.association(:firm)
856
-
857
- client.firm = companies(:another_firm)
858
- firm.reload
859
- assert_equal companies(:another_firm), firm.target
860
-
861
- client.client_of = companies(:first_firm).id
862
- firm.reload
863
- assert_equal companies(:first_firm), firm.target
864
- end
865
-
866
- def test_polymorphic_counter_cache
867
- tagging = taggings(:welcome_general)
868
- post = posts(:welcome)
869
- comment = comments(:greetings)
870
-
871
- assert_difference lambda { post.reload.tags_count }, -1 do
872
- assert_difference 'comment.reload.tags_count', +1 do
873
- tagging.taggable = comment
874
- end
875
- end
876
- end
877
-
878
- def test_polymorphic_with_custom_foreign_type
879
- sponsor = sponsors(:moustache_club_sponsor_for_groucho)
880
- groucho = members(:groucho)
881
- other = members(:some_other_guy)
882
-
883
- assert_equal groucho, sponsor.sponsorable
884
- assert_equal groucho, sponsor.thing
885
-
886
- sponsor.thing = other
887
-
888
- assert_equal other, sponsor.sponsorable
889
- assert_equal other, sponsor.thing
890
-
891
- sponsor.sponsorable = groucho
892
-
893
- assert_equal groucho, sponsor.sponsorable
894
- assert_equal groucho, sponsor.thing
895
- end
896
-
897
- def test_build_with_conditions
898
- client = companies(:second_client)
899
- firm = client.build_bob_firm
900
-
901
- assert_equal "Bob", firm.name
902
- end
903
-
904
- def test_create_with_conditions
905
- client = companies(:second_client)
906
- firm = client.create_bob_firm
907
-
908
- assert_equal "Bob", firm.name
909
- end
910
-
911
- def test_create_bang_with_conditions
912
- client = companies(:second_client)
913
- firm = client.create_bob_firm!
914
-
915
- assert_equal "Bob", firm.name
916
- end
917
-
918
- def test_build_with_block
919
- client = Client.create(:name => 'Client Company')
920
-
921
- firm = client.build_firm{ |f| f.name = 'Agency Company' }
922
- assert_equal 'Agency Company', firm.name
923
- end
924
-
925
- def test_create_with_block
926
- client = Client.create(:name => 'Client Company')
927
-
928
- firm = client.create_firm{ |f| f.name = 'Agency Company' }
929
- assert_equal 'Agency Company', firm.name
930
- end
931
-
932
- def test_create_bang_with_block
933
- client = Client.create(:name => 'Client Company')
934
-
935
- firm = client.create_firm!{ |f| f.name = 'Agency Company' }
936
- assert_equal 'Agency Company', firm.name
937
- end
938
-
939
- def test_should_set_foreign_key_on_create_association
940
- client = Client.create! :name => "fuu"
941
-
942
- firm = client.create_firm :name => "baa"
943
- assert_equal firm.id, client.client_of
944
- end
945
-
946
- def test_should_set_foreign_key_on_create_association!
947
- client = Client.create! :name => "fuu"
948
-
949
- firm = client.create_firm! :name => "baa"
950
- assert_equal firm.id, client.client_of
951
- end
952
-
953
- def test_self_referential_belongs_to_with_counter_cache_assigning_nil
954
- comment = Comment.create! :post => posts(:thinking), :body => "fuu"
955
- comment.parent = nil
956
- comment.save!
957
-
958
- assert_equal nil, comment.reload.parent
959
- assert_equal 0, comments(:greetings).reload.children_count
960
- end
961
-
962
- def test_belongs_to_with_id_assigning
963
- post = posts(:welcome)
964
- comment = Comment.create! body: "foo", post: post
965
- parent = comments(:greetings)
966
- assert_equal 0, parent.reload.children_count
967
- comment.parent_id = parent.id
968
-
969
- comment.save!
970
- assert_equal 1, parent.reload.children_count
971
- end
972
-
973
- def test_polymorphic_with_custom_primary_key
974
- toy = Toy.create!
975
- sponsor = Sponsor.create!(:sponsorable => toy)
976
-
977
- assert_equal toy, sponsor.reload.sponsorable
978
- end
979
-
980
- test "stale tracking doesn't care about the type" do
981
- apple = Firm.create("name" => "Apple")
982
- citibank = Account.create("credit_limit" => 10)
983
-
984
- citibank.firm_id = apple.id
985
- citibank.firm # load it
986
-
987
- citibank.firm_id = apple.id.to_s
988
-
989
- assert !citibank.association(:firm).stale_target?
990
- end
991
-
992
- def test_reflect_the_most_recent_change
993
- author1, author2 = Author.limit(2)
994
- post = Post.new(:title => "foo", :body=> "bar")
995
-
996
- post.author = author1
997
- post.author_id = author2.id
998
-
999
- assert post.save
1000
- assert_equal post.author_id, author2.id
1001
- end
1002
-
1003
- test 'dangerous association name raises ArgumentError' do
1004
- [:errors, 'errors', :save, 'save'].each do |name|
1005
- assert_raises(ArgumentError, "Association #{name} should not be allowed") do
1006
- Class.new(ActiveRecord::Base) do
1007
- belongs_to name
1008
- end
1009
- end
1010
- end
1011
- end
1012
-
1013
- test 'belongs_to works with model called Record' do
1014
- record = Record.create!
1015
- Column.create! record: record
1016
- assert_equal 1, Column.count
1017
- end
1018
- end
1019
-
1020
- class BelongsToWithForeignKeyTest < ActiveRecord::TestCase
1021
- fixtures :authors, :author_addresses
1022
-
1023
- def test_destroy_linked_models
1024
- address = AuthorAddress.create!
1025
- author = Author.create! name: "Author", author_address_id: address.id
1026
-
1027
- author.destroy!
1028
- end
1029
- end
1
+ require 'cases/helper'
2
+ require 'models/developer'
3
+ require 'models/computer'
4
+ require 'models/project'
5
+ require 'models/company'
6
+ require 'models/topic'
7
+ require 'models/reply'
8
+ require 'models/computer'
9
+ require 'models/post'
10
+ require 'models/author'
11
+ require 'models/tag'
12
+ require 'models/tagging'
13
+ require 'models/comment'
14
+ require 'models/sponsor'
15
+ require 'models/member'
16
+ require 'models/essay'
17
+ require 'models/toy'
18
+ require 'models/invoice'
19
+ require 'models/line_item'
20
+ require 'models/column'
21
+ require 'models/record'
22
+ require 'models/admin'
23
+ require 'models/admin/user'
24
+ require 'models/ship'
25
+ require 'models/treasure'
26
+ require 'models/parrot'
27
+
28
+ class BelongsToAssociationsTest < ActiveRecord::TestCase
29
+ fixtures :accounts, :companies, :developers, :projects, :topics,
30
+ :developers_projects, :computers, :authors, :author_addresses,
31
+ :posts, :tags, :taggings, :comments, :sponsors, :members
32
+
33
+ def test_belongs_to
34
+ firm = Client.find(3).firm
35
+ assert_not_nil firm
36
+ assert_equal companies(:first_firm).name, firm.name
37
+ end
38
+
39
+ def test_belongs_to_does_not_use_order_by
40
+ ActiveRecord::SQLCounter.clear_log
41
+ Client.find(3).firm
42
+ ensure
43
+ assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query'
44
+ end
45
+
46
+ def test_belongs_to_with_primary_key
47
+ client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
48
+ assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
49
+ end
50
+
51
+ def test_belongs_to_with_primary_key_joins_on_correct_column
52
+ sql = Client.joins(:firm_with_primary_key).to_sql
53
+ if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
54
+ assert_no_match(/`firm_with_primary_keys_companies`\.`id`/, sql)
55
+ assert_match(/`firm_with_primary_keys_companies`\.`name`/, sql)
56
+ elsif current_adapter?(:OracleAdapter)
57
+ # on Oracle aliases are truncated to 30 characters and are quoted in uppercase
58
+ assert_no_match(/"firm_with_primary_keys_compani"\."id"/i, sql)
59
+ assert_match(/"firm_with_primary_keys_compani"\."name"/i, sql)
60
+ elsif current_adapter?(:IBM_DBAdapter)
61
+ # Quoting of column names is not necessary for IBM_DB
62
+ assert_no_match(/firm_with_primary_keys_companies\.id/i, sql)
63
+ assert_match(/firm_with_primary_keys_companies\.name/i, sql)
64
+ else
65
+ assert_no_match(/"firm_with_primary_keys_companies"\."id"/, sql)
66
+ assert_match(/"firm_with_primary_keys_companies"\."name"/, sql)
67
+ end
68
+ end
69
+
70
+ def test_default_scope_on_relations_is_not_cached
71
+ counter = 0
72
+
73
+ comments = Class.new(ActiveRecord::Base) {
74
+ self.table_name = 'comments'
75
+ self.inheritance_column = 'not_there'
76
+
77
+ posts = Class.new(ActiveRecord::Base) {
78
+ self.table_name = 'posts'
79
+ self.inheritance_column = 'not_there'
80
+
81
+ default_scope -> {
82
+ counter += 1
83
+ where("id = :inc", :inc => counter)
84
+ }
85
+
86
+ has_many :comments, :anonymous_class => comments
87
+ }
88
+ belongs_to :post, :anonymous_class => posts, :inverse_of => false
89
+ }
90
+
91
+ assert_equal 0, counter
92
+ comment = comments.first
93
+ assert_equal 0, counter
94
+ sql = capture_sql { comment.post }
95
+ comment.reload
96
+ assert_not_equal sql, capture_sql { comment.post }
97
+ end
98
+
99
+ def test_proxy_assignment
100
+ account = Account.find(1)
101
+ assert_nothing_raised { account.firm = account.firm }
102
+ end
103
+
104
+ def test_type_mismatch
105
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
106
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
107
+ end
108
+
109
+ def test_raises_type_mismatch_with_namespaced_class
110
+ assert_nil defined?(Region), "This test requires that there is no top-level Region class"
111
+
112
+ ActiveRecord::Base.connection.instance_eval do
113
+ create_table(:admin_regions) { |t| t.string :name }
114
+ add_column :admin_users, :region_id, :integer
115
+ end
116
+ Admin.const_set "RegionalUser", Class.new(Admin::User) { belongs_to(:region) }
117
+ Admin.const_set "Region", Class.new(ActiveRecord::Base)
118
+
119
+ e = assert_raise(ActiveRecord::AssociationTypeMismatch) {
120
+ Admin::RegionalUser.new(region: 'wrong value')
121
+ }
122
+ assert_match(/^Region\([^)]+\) expected, got String\([^)]+\)$/, e.message)
123
+ ensure
124
+ Admin.send :remove_const, "Region" if Admin.const_defined?("Region")
125
+ Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser")
126
+
127
+ ActiveRecord::Base.connection.instance_eval do
128
+ remove_column :admin_users, :region_id if column_exists?(:admin_users, :region_id)
129
+ drop_table :admin_regions, if_exists: true
130
+ end
131
+ end
132
+
133
+ def test_natural_assignment
134
+ apple = Firm.create("name" => "Apple")
135
+ citibank = Account.create("credit_limit" => 10)
136
+ citibank.firm = apple
137
+ assert_equal apple.id, citibank.firm_id
138
+ end
139
+
140
+ def test_id_assignment
141
+ apple = Firm.create("name" => "Apple")
142
+ citibank = Account.create("credit_limit" => 10)
143
+ citibank.firm_id = apple
144
+ assert_nil citibank.firm_id
145
+ end
146
+
147
+ def test_natural_assignment_with_primary_key
148
+ apple = Firm.create("name" => "Apple")
149
+ citibank = Client.create("name" => "Primary key client")
150
+ citibank.firm_with_primary_key = apple
151
+ assert_equal apple.name, citibank.firm_name
152
+ end
153
+
154
+ def test_eager_loading_with_primary_key
155
+ Firm.create("name" => "Apple")
156
+ Client.create("name" => "Citibank", :firm_name => "Apple")
157
+ citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key).first
158
+ assert citibank_result.association(:firm_with_primary_key).loaded?
159
+ end
160
+
161
+ def test_eager_loading_with_primary_key_as_symbol
162
+ Firm.create("name" => "Apple")
163
+ Client.create("name" => "Citibank", :firm_name => "Apple")
164
+ citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key_symbols).first
165
+ assert citibank_result.association(:firm_with_primary_key_symbols).loaded?
166
+ end
167
+
168
+ def test_creating_the_belonging_object
169
+ citibank = Account.create("credit_limit" => 10)
170
+ apple = citibank.create_firm("name" => "Apple")
171
+ assert_equal apple, citibank.firm
172
+ citibank.save
173
+ citibank.reload
174
+ assert_equal apple, citibank.firm
175
+ end
176
+
177
+ def test_creating_the_belonging_object_with_primary_key
178
+ client = Client.create(:name => "Primary key client")
179
+ apple = client.create_firm_with_primary_key("name" => "Apple")
180
+ assert_equal apple, client.firm_with_primary_key
181
+ client.save
182
+ client.reload
183
+ assert_equal apple, client.firm_with_primary_key
184
+ end
185
+
186
+ def test_building_the_belonging_object
187
+ citibank = Account.create("credit_limit" => 10)
188
+ apple = citibank.build_firm("name" => "Apple")
189
+ citibank.save
190
+ assert_equal apple.id, citibank.firm_id
191
+ end
192
+
193
+ def test_building_the_belonging_object_with_implicit_sti_base_class
194
+ account = Account.new
195
+ company = account.build_firm
196
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
197
+ end
198
+
199
+ def test_building_the_belonging_object_with_explicit_sti_base_class
200
+ account = Account.new
201
+ company = account.build_firm(:type => "Company")
202
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
203
+ end
204
+
205
+ def test_building_the_belonging_object_with_sti_subclass
206
+ account = Account.new
207
+ company = account.build_firm(:type => "Firm")
208
+ assert_kind_of Firm, company, "Expected #{company.class} to be a Firm"
209
+ end
210
+
211
+ def test_building_the_belonging_object_with_an_invalid_type
212
+ account = Account.new
213
+ assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "InvalidType") }
214
+ end
215
+
216
+ def test_building_the_belonging_object_with_an_unrelated_type
217
+ account = Account.new
218
+ assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "Account") }
219
+ end
220
+
221
+ def test_building_the_belonging_object_with_primary_key
222
+ client = Client.create(:name => "Primary key client")
223
+ apple = client.build_firm_with_primary_key("name" => "Apple")
224
+ client.save
225
+ assert_equal apple.name, client.firm_name
226
+ end
227
+
228
+ def test_create!
229
+ client = Client.create!(:name => "Jimmy")
230
+ account = client.create_account!(:credit_limit => 10)
231
+ assert_equal account, client.account
232
+ assert account.persisted?
233
+ client.save
234
+ client.reload
235
+ assert_equal account, client.account
236
+ end
237
+
238
+ def test_failing_create!
239
+ client = Client.create!(:name => "Jimmy")
240
+ assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
241
+ assert_not_nil client.account
242
+ assert client.account.new_record?
243
+ end
244
+
245
+ def test_natural_assignment_to_nil
246
+ client = Client.find(3)
247
+ client.firm = nil
248
+ client.save
249
+ assert_nil client.firm(true)
250
+ assert_nil client.client_of
251
+ end
252
+
253
+ def test_natural_assignment_to_nil_with_primary_key
254
+ client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
255
+ client.firm_with_primary_key = nil
256
+ client.save
257
+ assert_nil client.firm_with_primary_key(true)
258
+ assert_nil client.client_of
259
+ end
260
+
261
+ def test_with_different_class_name
262
+ assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
263
+ assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
264
+ end
265
+
266
+ def test_with_condition
267
+ assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
268
+ assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
269
+ end
270
+
271
+ def test_polymorphic_association_class
272
+ sponsor = Sponsor.new
273
+ assert_nil sponsor.association(:sponsorable).send(:klass)
274
+ assert_nil sponsor.sponsorable(force_reload: true)
275
+
276
+ sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL
277
+ assert_nil sponsor.association(:sponsorable).send(:klass)
278
+ assert_nil sponsor.sponsorable(force_reload: true)
279
+
280
+ sponsor.sponsorable = Member.new :name => "Bert"
281
+ assert_equal Member, sponsor.association(:sponsorable).send(:klass)
282
+ assert_equal "members", sponsor.association(:sponsorable).aliased_table_name
283
+ end
284
+
285
+ def test_with_polymorphic_and_condition
286
+ sponsor = Sponsor.create
287
+ member = Member.create :name => "Bert"
288
+ sponsor.sponsorable = member
289
+
290
+ assert_equal member, sponsor.sponsorable
291
+ assert_nil sponsor.sponsorable_with_conditions
292
+ end
293
+
294
+ def test_with_select
295
+ assert_equal 1, Company.find(2).firm_with_select.attributes.size
296
+ assert_equal 1, Company.all.merge!(:includes => :firm_with_select ).find(2).firm_with_select.attributes.size
297
+ end
298
+
299
+ def test_belongs_to_without_counter_cache_option
300
+ # Ship has a conventionally named `treasures_count` column, but the counter_cache
301
+ # option is not given on the association.
302
+ ship = Ship.create(name: 'Countless')
303
+
304
+ assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
305
+ treasure = Treasure.new(name: 'Gold', ship: ship)
306
+ treasure.save
307
+ end
308
+
309
+ assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
310
+ treasure = ship.treasures.first
311
+ treasure.destroy
312
+ end
313
+ end
314
+
315
+ def test_belongs_to_counter
316
+ debate = Topic.create("title" => "debate")
317
+ assert_equal 0, debate.read_attribute("replies_count"), "No replies yet"
318
+
319
+ trash = debate.replies.create("title" => "blah!", "content" => "world around!")
320
+ assert_equal 1, Topic.find(debate.id).read_attribute("replies_count"), "First reply created"
321
+
322
+ trash.destroy
323
+ assert_equal 0, Topic.find(debate.id).read_attribute("replies_count"), "First reply deleted"
324
+ end
325
+
326
+ def test_belongs_to_counter_with_assigning_nil
327
+ post = Post.find(1)
328
+ comment = Comment.find(1)
329
+
330
+ assert_equal post.id, comment.post_id
331
+ assert_equal 2, Post.find(post.id).comments.size
332
+
333
+ comment.post = nil
334
+
335
+ assert_equal 1, Post.find(post.id).comments.size
336
+ end
337
+
338
+ def test_belongs_to_with_primary_key_counter
339
+ debate = Topic.create("title" => "debate")
340
+ debate2 = Topic.create("title" => "debate2")
341
+ reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
342
+
343
+ assert_equal 1, debate.reload.replies_count
344
+ assert_equal 0, debate2.reload.replies_count
345
+
346
+ reply.topic_with_primary_key = debate2
347
+
348
+ assert_equal 0, debate.reload.replies_count
349
+ assert_equal 1, debate2.reload.replies_count
350
+
351
+ reply.topic_with_primary_key = nil
352
+
353
+ assert_equal 0, debate.reload.replies_count
354
+ assert_equal 0, debate2.reload.replies_count
355
+ end
356
+
357
+ def test_belongs_to_counter_with_reassigning
358
+ topic1 = Topic.create("title" => "t1")
359
+ topic2 = Topic.create("title" => "t2")
360
+ reply1 = Reply.new("title" => "r1", "content" => "r1")
361
+ reply1.topic = topic1
362
+
363
+ assert reply1.save
364
+ assert_equal 1, Topic.find(topic1.id).replies.size
365
+ assert_equal 0, Topic.find(topic2.id).replies.size
366
+
367
+ reply1.topic = Topic.find(topic2.id)
368
+
369
+ assert_no_queries do
370
+ reply1.topic = topic2
371
+ end
372
+
373
+ assert reply1.save
374
+ assert_equal 0, Topic.find(topic1.id).replies.size
375
+ assert_equal 1, Topic.find(topic2.id).replies.size
376
+
377
+ reply1.topic = nil
378
+
379
+ assert_equal 0, Topic.find(topic1.id).replies.size
380
+ assert_equal 0, Topic.find(topic2.id).replies.size
381
+
382
+ reply1.topic = topic1
383
+
384
+ assert_equal 1, Topic.find(topic1.id).replies.size
385
+ assert_equal 0, Topic.find(topic2.id).replies.size
386
+
387
+ reply1.destroy
388
+
389
+ assert_equal 0, Topic.find(topic1.id).replies.size
390
+ assert_equal 0, Topic.find(topic2.id).replies.size
391
+ end
392
+
393
+ def test_belongs_to_reassign_with_namespaced_models_and_counters
394
+ topic1 = Web::Topic.create("title" => "t1")
395
+ topic2 = Web::Topic.create("title" => "t2")
396
+ reply1 = Web::Reply.new("title" => "r1", "content" => "r1")
397
+ reply1.topic = topic1
398
+
399
+ assert reply1.save
400
+ assert_equal 1, Web::Topic.find(topic1.id).replies.size
401
+ assert_equal 0, Web::Topic.find(topic2.id).replies.size
402
+
403
+ reply1.topic = Web::Topic.find(topic2.id)
404
+
405
+ assert reply1.save
406
+ assert_equal 0, Web::Topic.find(topic1.id).replies.size
407
+ assert_equal 1, Web::Topic.find(topic2.id).replies.size
408
+ end
409
+
410
+ def test_belongs_to_counter_after_save
411
+ topic = Topic.create!(:title => "monday night")
412
+ topic.replies.create!(:title => "re: monday night", :content => "football")
413
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
414
+
415
+ topic.save!
416
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
417
+ end
418
+
419
+ def test_belongs_to_with_touch_option_on_touch
420
+ line_item = LineItem.create!
421
+ Invoice.create!(line_items: [line_item])
422
+
423
+ assert_queries(1) { line_item.touch }
424
+ end
425
+
426
+ def test_belongs_to_with_touch_option_on_touch_without_updated_at_attributes
427
+ assert_not LineItem.column_names.include?("updated_at")
428
+
429
+ line_item = LineItem.create!
430
+ invoice = Invoice.create!(line_items: [line_item])
431
+ initial = invoice.updated_at
432
+ line_item.touch
433
+
434
+ assert_not_equal initial, invoice.reload.updated_at
435
+ end
436
+
437
+ def test_belongs_to_with_touch_option_on_touch_and_removed_parent
438
+ line_item = LineItem.create!
439
+ Invoice.create!(line_items: [line_item])
440
+
441
+ line_item.invoice = nil
442
+
443
+ assert_queries(2) { line_item.touch }
444
+ end
445
+
446
+ def test_belongs_to_with_touch_option_on_update
447
+ line_item = LineItem.create!
448
+ Invoice.create!(line_items: [line_item])
449
+
450
+ assert_queries(2) { line_item.update amount: 10 }
451
+ end
452
+
453
+ def test_belongs_to_with_touch_option_on_empty_update
454
+ line_item = LineItem.create!
455
+ Invoice.create!(line_items: [line_item])
456
+
457
+ assert_queries(0) { line_item.save }
458
+ end
459
+
460
+ def test_belongs_to_with_touch_option_on_destroy
461
+ line_item = LineItem.create!
462
+ Invoice.create!(line_items: [line_item])
463
+
464
+ assert_queries(2) { line_item.destroy }
465
+ end
466
+
467
+ def test_belongs_to_with_touch_option_on_destroy_with_destroyed_parent
468
+ line_item = LineItem.create!
469
+ invoice = Invoice.create!(line_items: [line_item])
470
+ invoice.destroy
471
+
472
+ assert_queries(1) { line_item.destroy }
473
+ end
474
+
475
+ def test_belongs_to_with_touch_option_on_touch_and_reassigned_parent
476
+ line_item = LineItem.create!
477
+ Invoice.create!(line_items: [line_item])
478
+
479
+ line_item.invoice = Invoice.create!
480
+
481
+ assert_queries(3) { line_item.touch }
482
+ end
483
+
484
+ def test_belongs_to_counter_after_update
485
+ topic = Topic.create!(title: "37s")
486
+ topic.replies.create!(title: "re: 37s", content: "rails")
487
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
488
+
489
+ topic.update(title: "37signals")
490
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
491
+ end
492
+
493
+ def test_belongs_to_counter_when_update_columns
494
+ topic = Topic.create!(:title => "37s")
495
+ topic.replies.create!(:title => "re: 37s", :content => "rails")
496
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
497
+
498
+ topic.update_columns(content: "rails is wonderful")
499
+ assert_equal 1, Topic.find(topic.id)[:replies_count]
500
+ end
501
+
502
+ def test_assignment_before_child_saved
503
+ final_cut = Client.new("name" => "Final Cut")
504
+ firm = Firm.find(1)
505
+ final_cut.firm = firm
506
+ assert !final_cut.persisted?
507
+ assert final_cut.save
508
+ assert final_cut.persisted?
509
+ assert firm.persisted?
510
+ assert_equal firm, final_cut.firm
511
+ assert_equal firm, final_cut.firm(true)
512
+ end
513
+
514
+ def test_assignment_before_child_saved_with_primary_key
515
+ final_cut = Client.new("name" => "Final Cut")
516
+ firm = Firm.find(1)
517
+ final_cut.firm_with_primary_key = firm
518
+ assert !final_cut.persisted?
519
+ assert final_cut.save
520
+ assert final_cut.persisted?
521
+ assert firm.persisted?
522
+ assert_equal firm, final_cut.firm_with_primary_key
523
+ assert_equal firm, final_cut.firm_with_primary_key(true)
524
+ end
525
+
526
+ def test_new_record_with_foreign_key_but_no_object
527
+ client = Client.new("firm_id" => 1)
528
+ # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
529
+ assert_equal Firm.all.merge!(:order => "id").first, client.firm_with_basic_id
530
+ end
531
+
532
+ def test_setting_foreign_key_after_nil_target_loaded
533
+ client = Client.new
534
+ client.firm_with_basic_id
535
+ client.firm_id = 1
536
+
537
+ assert_equal companies(:first_firm), client.firm_with_basic_id
538
+ end
539
+
540
+ def test_polymorphic_setting_foreign_key_after_nil_target_loaded
541
+ sponsor = Sponsor.new
542
+ sponsor.sponsorable
543
+ sponsor.sponsorable_id = 1
544
+ sponsor.sponsorable_type = "Member"
545
+
546
+ assert_equal members(:groucho), sponsor.sponsorable
547
+ end
548
+
549
+ def test_dont_find_target_when_foreign_key_is_null
550
+ tagging = taggings(:thinking_general)
551
+ assert_queries(0) { tagging.super_tag }
552
+ end
553
+
554
+ def test_field_name_same_as_foreign_key
555
+ computer = Computer.find(1)
556
+ assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
557
+ end
558
+
559
+ def test_counter_cache
560
+ topic = Topic.create :title => "Zoom-zoom-zoom"
561
+ assert_equal 0, topic[:replies_count]
562
+
563
+ reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
564
+ reply.topic = topic
565
+
566
+ assert_equal 1, topic.reload[:replies_count]
567
+ assert_equal 1, topic.replies.size
568
+
569
+ topic[:replies_count] = 15
570
+ assert_equal 15, topic.replies.size
571
+ end
572
+
573
+ def test_counter_cache_double_destroy
574
+ topic = Topic.create :title => "Zoom-zoom-zoom"
575
+
576
+ 5.times do
577
+ topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
578
+ end
579
+
580
+ assert_equal 5, topic.reload[:replies_count]
581
+ assert_equal 5, topic.replies.size
582
+
583
+ reply = topic.replies.first
584
+
585
+ reply.destroy
586
+ assert_equal 4, topic.reload[:replies_count]
587
+
588
+ reply.destroy
589
+ assert_equal 4, topic.reload[:replies_count]
590
+ assert_equal 4, topic.replies.size
591
+ end
592
+
593
+ def test_concurrent_counter_cache_double_destroy
594
+ topic = Topic.create :title => "Zoom-zoom-zoom"
595
+
596
+ 5.times do
597
+ topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
598
+ end
599
+
600
+ assert_equal 5, topic.reload[:replies_count]
601
+ assert_equal 5, topic.replies.size
602
+
603
+ reply = topic.replies.first
604
+ reply_clone = Reply.find(reply.id)
605
+
606
+ reply.destroy
607
+ assert_equal 4, topic.reload[:replies_count]
608
+
609
+ reply_clone.destroy
610
+ assert_equal 4, topic.reload[:replies_count]
611
+ assert_equal 4, topic.replies.size
612
+ end
613
+
614
+ def test_custom_counter_cache
615
+ reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
616
+ assert_equal 0, reply[:replies_count]
617
+
618
+ silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
619
+ silly.reply = reply
620
+
621
+ assert_equal 1, reply.reload[:replies_count]
622
+ assert_equal 1, reply.replies.size
623
+
624
+ reply[:replies_count] = 17
625
+ assert_equal 17, reply.replies.size
626
+ end
627
+
628
+ def test_association_assignment_sticks
629
+ post = Post.first
630
+
631
+ author1, author2 = Author.all.merge!(:limit => 2).to_a
632
+ assert_not_nil author1
633
+ assert_not_nil author2
634
+
635
+ # make sure the association is loaded
636
+ post.author
637
+
638
+ # set the association by id, directly
639
+ post.author_id = author2.id
640
+
641
+ # save and reload
642
+ post.save!
643
+ post.reload
644
+
645
+ # the author id of the post should be the id we set
646
+ assert_equal post.author_id, author2.id
647
+ end
648
+
649
+ def test_cant_save_readonly_association
650
+ assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
651
+ assert companies(:first_client).readonly_firm.readonly?
652
+ end
653
+
654
+ def test_test_polymorphic_assignment_foreign_key_type_string
655
+ comment = Comment.first
656
+ comment.author = Author.first
657
+ comment.resource = Member.first
658
+ comment.save
659
+
660
+ assert_equal Comment.all.to_a,
661
+ Comment.includes(:author).to_a
662
+
663
+ assert_equal Comment.all.to_a,
664
+ Comment.includes(:resource).to_a
665
+ end
666
+
667
+ def test_polymorphic_assignment_foreign_type_field_updating
668
+ # should update when assigning a saved record
669
+ sponsor = Sponsor.new
670
+ member = Member.create
671
+ sponsor.sponsorable = member
672
+ assert_equal "Member", sponsor.sponsorable_type
673
+
674
+ # should update when assigning a new record
675
+ sponsor = Sponsor.new
676
+ member = Member.new
677
+ sponsor.sponsorable = member
678
+ assert_equal "Member", sponsor.sponsorable_type
679
+ end
680
+
681
+ def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating
682
+ # should update when assigning a saved record
683
+ essay = Essay.new
684
+ writer = Author.create(:name => "David")
685
+ essay.writer = writer
686
+ assert_equal "Author", essay.writer_type
687
+
688
+ # should update when assigning a new record
689
+ essay = Essay.new
690
+ writer = Author.new
691
+ essay.writer = writer
692
+ assert_equal "Author", essay.writer_type
693
+ end
694
+
695
+ def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
696
+ sponsor = Sponsor.new
697
+ saved_member = Member.create
698
+ new_member = Member.new
699
+
700
+ sponsor.sponsorable = saved_member
701
+ assert_equal saved_member.id, sponsor.sponsorable_id
702
+
703
+ sponsor.sponsorable = new_member
704
+ assert_nil sponsor.sponsorable_id
705
+ end
706
+
707
+ def test_assignment_updates_foreign_id_field_for_new_and_saved_records
708
+ client = Client.new
709
+ saved_firm = Firm.create :name => "Saved"
710
+ new_firm = Firm.new
711
+
712
+ client.firm = saved_firm
713
+ assert_equal saved_firm.id, client.client_of
714
+
715
+ client.firm = new_firm
716
+ assert_nil client.client_of
717
+ end
718
+
719
+ def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
720
+ essay = Essay.new
721
+ saved_writer = Author.create(:name => "David")
722
+ new_writer = Author.new
723
+
724
+ essay.writer = saved_writer
725
+ assert_equal saved_writer.name, essay.writer_id
726
+
727
+ essay.writer = new_writer
728
+ assert_nil essay.writer_id
729
+ end
730
+
731
+ def test_polymorphic_assignment_with_nil
732
+ essay = Essay.new
733
+ assert_nil essay.writer_id
734
+ assert_nil essay.writer_type
735
+
736
+ essay.writer_id = 1
737
+ essay.writer_type = 'Author'
738
+
739
+ essay.writer = nil
740
+ assert_nil essay.writer_id
741
+ assert_nil essay.writer_type
742
+ end
743
+
744
+ def test_belongs_to_proxy_should_not_respond_to_private_methods
745
+ assert_raise(NoMethodError) { companies(:first_firm).private_method }
746
+ assert_raise(NoMethodError) { companies(:second_client).firm.private_method }
747
+ end
748
+
749
+ def test_belongs_to_proxy_should_respond_to_private_methods_via_send
750
+ companies(:first_firm).send(:private_method)
751
+ companies(:second_client).firm.send(:private_method)
752
+ end
753
+
754
+ def test_save_of_record_with_loaded_belongs_to
755
+ @account = companies(:first_firm).account
756
+
757
+ assert_nothing_raised do
758
+ Account.find(@account.id).save!
759
+ Account.all.merge!(:includes => :firm).find(@account.id).save!
760
+ end
761
+
762
+ @account.firm.delete
763
+
764
+ assert_nothing_raised do
765
+ Account.find(@account.id).save!
766
+ Account.all.merge!(:includes => :firm).find(@account.id).save!
767
+ end
768
+ end
769
+
770
+ def test_dependent_delete_and_destroy_with_belongs_to
771
+ AuthorAddress.destroyed_author_address_ids.clear
772
+
773
+ author_address = author_addresses(:david_address)
774
+ author_address_extra = author_addresses(:david_address_extra)
775
+ assert_equal [], AuthorAddress.destroyed_author_address_ids
776
+
777
+ assert_difference "AuthorAddress.count", -2 do
778
+ authors(:david).destroy
779
+ end
780
+
781
+ assert_equal [], AuthorAddress.where(id: [author_address.id, author_address_extra.id])
782
+ assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids
783
+ end
784
+
785
+ def test_belongs_to_invalid_dependent_option_raises_exception
786
+ error = assert_raise ArgumentError do
787
+ Class.new(Author).belongs_to :special_author_address, :dependent => :nullify
788
+ end
789
+ assert_equal error.message, 'The :dependent option must be one of [:destroy, :delete], but is :nullify'
790
+ end
791
+
792
+ def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
793
+ new_firm = accounts(:signals37).build_firm(:name => 'Apple')
794
+ assert_equal new_firm.name, "Apple"
795
+ end
796
+
797
+ def test_attributes_are_set_without_error_when_initialized_from_belongs_to_association_with_array_in_where_clause
798
+ new_account = Account.where(:credit_limit => [ 50, 60 ]).new
799
+ assert_nil new_account.credit_limit
800
+ end
801
+
802
+ def test_reassigning_the_parent_id_updates_the_object
803
+ client = companies(:second_client)
804
+
805
+ client.firm
806
+ client.firm_with_condition
807
+ firm_proxy = client.send(:association_instance_get, :firm)
808
+ firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
809
+
810
+ assert !firm_proxy.stale_target?
811
+ assert !firm_with_condition_proxy.stale_target?
812
+ assert_equal companies(:first_firm), client.firm
813
+ assert_equal companies(:first_firm), client.firm_with_condition
814
+
815
+ client.client_of = companies(:another_firm).id
816
+
817
+ assert firm_proxy.stale_target?
818
+ assert firm_with_condition_proxy.stale_target?
819
+ assert_equal companies(:another_firm), client.firm
820
+ assert_equal companies(:another_firm), client.firm_with_condition
821
+ end
822
+
823
+ def test_polymorphic_reassignment_of_associated_id_updates_the_object
824
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
825
+
826
+ sponsor.sponsorable
827
+ proxy = sponsor.send(:association_instance_get, :sponsorable)
828
+
829
+ assert !proxy.stale_target?
830
+ assert_equal members(:groucho), sponsor.sponsorable
831
+
832
+ sponsor.sponsorable_id = members(:some_other_guy).id
833
+
834
+ assert proxy.stale_target?
835
+ assert_equal members(:some_other_guy), sponsor.sponsorable
836
+ end
837
+
838
+ def test_polymorphic_reassignment_of_associated_type_updates_the_object
839
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
840
+
841
+ sponsor.sponsorable
842
+ proxy = sponsor.send(:association_instance_get, :sponsorable)
843
+
844
+ assert !proxy.stale_target?
845
+ assert_equal members(:groucho), sponsor.sponsorable
846
+
847
+ sponsor.sponsorable_type = 'Firm'
848
+
849
+ assert proxy.stale_target?
850
+ assert_equal companies(:first_firm), sponsor.sponsorable
851
+ end
852
+
853
+ def test_reloading_association_with_key_change
854
+ client = companies(:second_client)
855
+ firm = client.association(:firm)
856
+
857
+ client.firm = companies(:another_firm)
858
+ firm.reload
859
+ assert_equal companies(:another_firm), firm.target
860
+
861
+ client.client_of = companies(:first_firm).id
862
+ firm.reload
863
+ assert_equal companies(:first_firm), firm.target
864
+ end
865
+
866
+ def test_polymorphic_counter_cache
867
+ tagging = taggings(:welcome_general)
868
+ post = posts(:welcome)
869
+ comment = comments(:greetings)
870
+
871
+ assert_difference lambda { post.reload.tags_count }, -1 do
872
+ assert_difference 'comment.reload.tags_count', +1 do
873
+ tagging.taggable = comment
874
+ end
875
+ end
876
+ end
877
+
878
+ def test_polymorphic_with_custom_foreign_type
879
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
880
+ groucho = members(:groucho)
881
+ other = members(:some_other_guy)
882
+
883
+ assert_equal groucho, sponsor.sponsorable
884
+ assert_equal groucho, sponsor.thing
885
+
886
+ sponsor.thing = other
887
+
888
+ assert_equal other, sponsor.sponsorable
889
+ assert_equal other, sponsor.thing
890
+
891
+ sponsor.sponsorable = groucho
892
+
893
+ assert_equal groucho, sponsor.sponsorable
894
+ assert_equal groucho, sponsor.thing
895
+ end
896
+
897
+ def test_build_with_conditions
898
+ client = companies(:second_client)
899
+ firm = client.build_bob_firm
900
+
901
+ assert_equal "Bob", firm.name
902
+ end
903
+
904
+ def test_create_with_conditions
905
+ client = companies(:second_client)
906
+ firm = client.create_bob_firm
907
+
908
+ assert_equal "Bob", firm.name
909
+ end
910
+
911
+ def test_create_bang_with_conditions
912
+ client = companies(:second_client)
913
+ firm = client.create_bob_firm!
914
+
915
+ assert_equal "Bob", firm.name
916
+ end
917
+
918
+ def test_build_with_block
919
+ client = Client.create(:name => 'Client Company')
920
+
921
+ firm = client.build_firm{ |f| f.name = 'Agency Company' }
922
+ assert_equal 'Agency Company', firm.name
923
+ end
924
+
925
+ def test_create_with_block
926
+ client = Client.create(:name => 'Client Company')
927
+
928
+ firm = client.create_firm{ |f| f.name = 'Agency Company' }
929
+ assert_equal 'Agency Company', firm.name
930
+ end
931
+
932
+ def test_create_bang_with_block
933
+ client = Client.create(:name => 'Client Company')
934
+
935
+ firm = client.create_firm!{ |f| f.name = 'Agency Company' }
936
+ assert_equal 'Agency Company', firm.name
937
+ end
938
+
939
+ def test_should_set_foreign_key_on_create_association
940
+ client = Client.create! :name => "fuu"
941
+
942
+ firm = client.create_firm :name => "baa"
943
+ assert_equal firm.id, client.client_of
944
+ end
945
+
946
+ def test_should_set_foreign_key_on_create_association!
947
+ client = Client.create! :name => "fuu"
948
+
949
+ firm = client.create_firm! :name => "baa"
950
+ assert_equal firm.id, client.client_of
951
+ end
952
+
953
+ def test_self_referential_belongs_to_with_counter_cache_assigning_nil
954
+ comment = Comment.create! :post => posts(:thinking), :body => "fuu"
955
+ comment.parent = nil
956
+ comment.save!
957
+
958
+ assert_equal nil, comment.reload.parent
959
+ assert_equal 0, comments(:greetings).reload.children_count
960
+ end
961
+
962
+ def test_belongs_to_with_id_assigning
963
+ post = posts(:welcome)
964
+ comment = Comment.create! body: "foo", post: post
965
+ parent = comments(:greetings)
966
+ assert_equal 0, parent.reload.children_count
967
+ comment.parent_id = parent.id
968
+
969
+ comment.save!
970
+ assert_equal 1, parent.reload.children_count
971
+ end
972
+
973
+ def test_polymorphic_with_custom_primary_key
974
+ toy = Toy.create!
975
+ sponsor = Sponsor.create!(:sponsorable => toy)
976
+
977
+ assert_equal toy, sponsor.reload.sponsorable
978
+ end
979
+
980
+ test "stale tracking doesn't care about the type" do
981
+ apple = Firm.create("name" => "Apple")
982
+ citibank = Account.create("credit_limit" => 10)
983
+
984
+ citibank.firm_id = apple.id
985
+ citibank.firm # load it
986
+
987
+ citibank.firm_id = apple.id.to_s
988
+
989
+ assert !citibank.association(:firm).stale_target?
990
+ end
991
+
992
+ def test_reflect_the_most_recent_change
993
+ author1, author2 = Author.limit(2)
994
+ post = Post.new(:title => "foo", :body=> "bar")
995
+
996
+ post.author = author1
997
+ post.author_id = author2.id
998
+
999
+ assert post.save
1000
+ assert_equal post.author_id, author2.id
1001
+ end
1002
+
1003
+ test 'dangerous association name raises ArgumentError' do
1004
+ [:errors, 'errors', :save, 'save'].each do |name|
1005
+ assert_raises(ArgumentError, "Association #{name} should not be allowed") do
1006
+ Class.new(ActiveRecord::Base) do
1007
+ belongs_to name
1008
+ end
1009
+ end
1010
+ end
1011
+ end
1012
+
1013
+ test 'belongs_to works with model called Record' do
1014
+ record = Record.create!
1015
+ Column.create! record: record
1016
+ assert_equal 1, Column.count
1017
+ end
1018
+ end
1019
+
1020
+ class BelongsToWithForeignKeyTest < ActiveRecord::TestCase
1021
+ fixtures :authors, :author_addresses
1022
+
1023
+ def test_destroy_linked_models
1024
+ address = AuthorAddress.create!
1025
+ author = Author.create! name: "Author", author_address_id: address.id
1026
+
1027
+ author.destroy!
1028
+ end
1029
+ end