PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/rails/activerecord/test/associations_test.rb

https://github.com/millbanksystems/epetitions
Ruby | 1896 lines | 1685 code | 200 blank | 11 comment | 2 complexity | fc32bf3c8c7a5200a9af4d310bfa9cfd MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. require 'abstract_unit'
  2. require 'fixtures/developer'
  3. require 'fixtures/project'
  4. require 'fixtures/company'
  5. require 'fixtures/topic'
  6. require 'fixtures/reply'
  7. require 'fixtures/computer'
  8. require 'fixtures/customer'
  9. require 'fixtures/order'
  10. require 'fixtures/categorization'
  11. require 'fixtures/category'
  12. require 'fixtures/post'
  13. require 'fixtures/author'
  14. require 'fixtures/comment'
  15. require 'fixtures/tag'
  16. require 'fixtures/tagging'
  17. class AssociationsTest < Test::Unit::TestCase
  18. fixtures :accounts, :companies, :developers, :projects, :developers_projects,
  19. :computers
  20. def test_bad_collection_keys
  21. assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do
  22. Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
  23. end
  24. end
  25. def test_force_reload
  26. firm = Firm.new("name" => "A New Firm, Inc")
  27. firm.save
  28. firm.clients.each {|c|} # forcing to load all clients
  29. assert firm.clients.empty?, "New firm shouldn't have client objects"
  30. assert_equal 0, firm.clients.size, "New firm should have 0 clients"
  31. client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
  32. client.save
  33. assert firm.clients.empty?, "New firm should have cached no client objects"
  34. assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
  35. assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
  36. assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count"
  37. end
  38. def test_storing_in_pstore
  39. require "tmpdir"
  40. store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
  41. File.delete(store_filename) if File.exists?(store_filename)
  42. require "pstore"
  43. apple = Firm.create("name" => "Apple")
  44. natural = Client.new("name" => "Natural Company")
  45. apple.clients << natural
  46. db = PStore.new(store_filename)
  47. db.transaction do
  48. db["apple"] = apple
  49. end
  50. db = PStore.new(store_filename)
  51. db.transaction do
  52. assert_equal "Natural Company", db["apple"].clients.first.name
  53. end
  54. end
  55. end
  56. class AssociationProxyTest < Test::Unit::TestCase
  57. fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
  58. def test_proxy_accessors
  59. welcome = posts(:welcome)
  60. assert_equal welcome, welcome.author.proxy_owner
  61. assert_equal welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
  62. welcome.author.class # force load target
  63. assert_equal welcome.author, welcome.author.proxy_target
  64. david = authors(:david)
  65. assert_equal david, david.posts.proxy_owner
  66. assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
  67. david.posts.first # force load target
  68. assert_equal david.posts, david.posts.proxy_target
  69. assert_equal david, david.posts_with_extension.testing_proxy_owner
  70. assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
  71. david.posts_with_extension.first # force load target
  72. assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
  73. end
  74. def test_push_does_not_load_target
  75. david = authors(:david)
  76. david.categories << categories(:technology)
  77. assert !david.categories.loaded?
  78. assert david.categories.include?(categories(:technology))
  79. end
  80. def test_save_on_parent_does_not_load_target
  81. david = developers(:david)
  82. assert !david.projects.loaded?
  83. david.update_attribute(:created_at, Time.now)
  84. assert !david.projects.loaded?
  85. end
  86. end
  87. class HasOneAssociationsTest < Test::Unit::TestCase
  88. fixtures :accounts, :companies, :developers, :projects, :developers_projects
  89. def setup
  90. Account.destroyed_account_ids.clear
  91. end
  92. def test_has_one
  93. assert_equal companies(:first_firm).account, Account.find(1)
  94. assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
  95. end
  96. def test_has_one_cache_nils
  97. firm = companies(:another_firm)
  98. assert_queries(1) { assert_nil firm.account }
  99. assert_queries(0) { assert_nil firm.account }
  100. firms = Firm.find(:all, :include => :account)
  101. assert_queries(0) { firms.each(&:account) }
  102. end
  103. def test_can_marshal_has_one_association_with_nil_target
  104. firm = Firm.new
  105. assert_nothing_raised do
  106. assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
  107. end
  108. firm.account
  109. assert_nothing_raised do
  110. assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
  111. end
  112. end
  113. def test_proxy_assignment
  114. company = companies(:first_firm)
  115. assert_nothing_raised { company.account = company.account }
  116. end
  117. def test_triple_equality
  118. assert Account === companies(:first_firm).account
  119. assert companies(:first_firm).account === Account
  120. end
  121. def test_type_mismatch
  122. assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
  123. assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
  124. end
  125. def test_natural_assignment
  126. apple = Firm.create("name" => "Apple")
  127. citibank = Account.create("credit_limit" => 10)
  128. apple.account = citibank
  129. assert_equal apple.id, citibank.firm_id
  130. end
  131. def test_natural_assignment_to_nil
  132. old_account_id = companies(:first_firm).account.id
  133. companies(:first_firm).account = nil
  134. companies(:first_firm).save
  135. assert_nil companies(:first_firm).account
  136. # account is dependent, therefore is destroyed when reference to owner is lost
  137. assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
  138. end
  139. def test_assignment_without_replacement
  140. apple = Firm.create("name" => "Apple")
  141. citibank = Account.create("credit_limit" => 10)
  142. apple.account = citibank
  143. assert_equal apple.id, citibank.firm_id
  144. hsbc = apple.build_account({ :credit_limit => 20}, false)
  145. assert_equal apple.id, hsbc.firm_id
  146. hsbc.save
  147. assert_equal apple.id, citibank.firm_id
  148. nykredit = apple.create_account({ :credit_limit => 30}, false)
  149. assert_equal apple.id, nykredit.firm_id
  150. assert_equal apple.id, citibank.firm_id
  151. assert_equal apple.id, hsbc.firm_id
  152. end
  153. def test_assignment_without_replacement_on_create
  154. apple = Firm.create("name" => "Apple")
  155. citibank = Account.create("credit_limit" => 10)
  156. apple.account = citibank
  157. assert_equal apple.id, citibank.firm_id
  158. hsbc = apple.create_account({:credit_limit => 10}, false)
  159. assert_equal apple.id, hsbc.firm_id
  160. hsbc.save
  161. assert_equal apple.id, citibank.firm_id
  162. end
  163. def test_dependence
  164. num_accounts = Account.count
  165. firm = Firm.find(1)
  166. assert !firm.account.nil?
  167. account_id = firm.account.id
  168. assert_equal [], Account.destroyed_account_ids[firm.id]
  169. firm.destroy
  170. assert_equal num_accounts - 1, Account.count
  171. assert_equal [account_id], Account.destroyed_account_ids[firm.id]
  172. end
  173. def test_exclusive_dependence
  174. num_accounts = Account.count
  175. firm = ExclusivelyDependentFirm.find(9)
  176. assert !firm.account.nil?
  177. account_id = firm.account.id
  178. assert_equal [], Account.destroyed_account_ids[firm.id]
  179. firm.destroy
  180. assert_equal num_accounts - 1, Account.count
  181. assert_equal [], Account.destroyed_account_ids[firm.id]
  182. end
  183. def test_dependence_with_nil_associate
  184. firm = DependentFirm.new(:name => 'nullify')
  185. firm.save!
  186. assert_nothing_raised { firm.destroy }
  187. end
  188. def test_succesful_build_association
  189. firm = Firm.new("name" => "GlobalMegaCorp")
  190. firm.save
  191. account = firm.build_account("credit_limit" => 1000)
  192. assert account.save
  193. assert_equal account, firm.account
  194. end
  195. def test_failing_build_association
  196. firm = Firm.new("name" => "GlobalMegaCorp")
  197. firm.save
  198. account = firm.build_account
  199. assert !account.save
  200. assert_equal "can't be empty", account.errors.on("credit_limit")
  201. end
  202. def test_build_association_twice_without_saving_affects_nothing
  203. count_of_account = Account.count
  204. firm = Firm.find(:first)
  205. account1 = firm.build_account("credit_limit" => 1000)
  206. account2 = firm.build_account("credit_limit" => 2000)
  207. assert_equal count_of_account, Account.count
  208. end
  209. def test_create_association
  210. firm = Firm.create(:name => "GlobalMegaCorp")
  211. account = firm.create_account(:credit_limit => 1000)
  212. assert_equal account, firm.reload.account
  213. end
  214. def test_build
  215. firm = Firm.new("name" => "GlobalMegaCorp")
  216. firm.save
  217. firm.account = account = Account.new("credit_limit" => 1000)
  218. assert_equal account, firm.account
  219. assert account.save
  220. assert_equal account, firm.account
  221. end
  222. def test_build_before_child_saved
  223. firm = Firm.find(1)
  224. account = firm.account.build("credit_limit" => 1000)
  225. assert_equal account, firm.account
  226. assert account.new_record?
  227. assert firm.save
  228. assert_equal account, firm.account
  229. assert !account.new_record?
  230. end
  231. def test_build_before_either_saved
  232. firm = Firm.new("name" => "GlobalMegaCorp")
  233. firm.account = account = Account.new("credit_limit" => 1000)
  234. assert_equal account, firm.account
  235. assert account.new_record?
  236. assert firm.save
  237. assert_equal account, firm.account
  238. assert !account.new_record?
  239. end
  240. def test_failing_build_association
  241. firm = Firm.new("name" => "GlobalMegaCorp")
  242. firm.save
  243. firm.account = account = Account.new
  244. assert_equal account, firm.account
  245. assert !account.save
  246. assert_equal account, firm.account
  247. assert_equal "can't be empty", account.errors.on("credit_limit")
  248. end
  249. def test_create
  250. firm = Firm.new("name" => "GlobalMegaCorp")
  251. firm.save
  252. firm.account = account = Account.create("credit_limit" => 1000)
  253. assert_equal account, firm.account
  254. end
  255. def test_create_before_save
  256. firm = Firm.new("name" => "GlobalMegaCorp")
  257. firm.account = account = Account.create("credit_limit" => 1000)
  258. assert_equal account, firm.account
  259. end
  260. def test_dependence_with_missing_association
  261. Account.destroy_all
  262. firm = Firm.find(1)
  263. assert firm.account.nil?
  264. firm.destroy
  265. end
  266. def test_dependence_with_missing_association_and_nullify
  267. Account.destroy_all
  268. firm = DependentFirm.find(:first)
  269. assert firm.account.nil?
  270. firm.destroy
  271. end
  272. def test_assignment_before_parent_saved
  273. firm = Firm.new("name" => "GlobalMegaCorp")
  274. firm.account = a = Account.find(1)
  275. assert firm.new_record?
  276. assert_equal a, firm.account
  277. assert firm.save
  278. assert_equal a, firm.account
  279. assert_equal a, firm.account(true)
  280. end
  281. def test_finding_with_interpolated_condition
  282. firm = Firm.find(:first)
  283. superior = firm.clients.create(:name => 'SuperiorCo')
  284. superior.rating = 10
  285. superior.save
  286. assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
  287. end
  288. def test_assignment_before_child_saved
  289. firm = Firm.find(1)
  290. firm.account = a = Account.new("credit_limit" => 1000)
  291. assert !a.new_record?
  292. assert_equal a, firm.account
  293. assert_equal a, firm.account
  294. assert_equal a, firm.account(true)
  295. end
  296. def test_assignment_before_either_saved
  297. firm = Firm.new("name" => "GlobalMegaCorp")
  298. firm.account = a = Account.new("credit_limit" => 1000)
  299. assert firm.new_record?
  300. assert a.new_record?
  301. assert_equal a, firm.account
  302. assert firm.save
  303. assert !firm.new_record?
  304. assert !a.new_record?
  305. assert_equal a, firm.account
  306. assert_equal a, firm.account(true)
  307. end
  308. def test_not_resaved_when_unchanged
  309. firm = Firm.find(:first, :include => :account)
  310. assert_queries(1) { firm.save! }
  311. firm = Firm.find(:first)
  312. firm.account = Account.find(:first)
  313. assert_queries(1) { firm.save! }
  314. firm = Firm.find(:first).clone
  315. firm.account = Account.find(:first)
  316. assert_queries(2) { firm.save! }
  317. firm = Firm.find(:first).clone
  318. firm.account = Account.find(:first).clone
  319. assert_queries(2) { firm.save! }
  320. end
  321. def test_save_still_works_after_accessing_nil_has_one
  322. jp = Company.new :name => 'Jaded Pixel'
  323. jp.dummy_account.nil?
  324. assert_nothing_raised do
  325. jp.save!
  326. end
  327. end
  328. end
  329. class HasManyAssociationsTest < Test::Unit::TestCase
  330. fixtures :accounts, :companies, :developers, :projects,
  331. :developers_projects, :topics, :authors, :comments
  332. def setup
  333. Client.destroyed_client_ids.clear
  334. end
  335. def force_signal37_to_load_all_clients_of_firm
  336. companies(:first_firm).clients_of_firm.each {|f| }
  337. end
  338. def test_counting_with_counter_sql
  339. assert_equal 2, Firm.find(:first).clients.count
  340. end
  341. def test_counting
  342. assert_equal 2, Firm.find(:first).plain_clients.count
  343. end
  344. def test_counting_with_single_conditions
  345. assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
  346. end
  347. def test_counting_with_single_hash
  348. assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
  349. end
  350. def test_counting_with_column_name_and_hash
  351. assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
  352. end
  353. def test_finding
  354. assert_equal 2, Firm.find(:first).clients.length
  355. end
  356. def test_find_many_with_merged_options
  357. assert_equal 1, companies(:first_firm).limited_clients.size
  358. assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
  359. assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size
  360. end
  361. def test_triple_equality
  362. assert !(Array === Firm.find(:first).clients)
  363. assert Firm.find(:first).clients === Array
  364. end
  365. def test_finding_default_orders
  366. assert_equal "Summit", Firm.find(:first).clients.first.name
  367. end
  368. def test_finding_with_different_class_name_and_order
  369. assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
  370. end
  371. def test_finding_with_foreign_key
  372. assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
  373. end
  374. def test_finding_with_condition
  375. assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
  376. end
  377. def test_finding_with_condition_hash
  378. assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
  379. end
  380. def test_finding_using_sql
  381. firm = Firm.find(:first)
  382. first_client = firm.clients_using_sql.first
  383. assert_not_nil first_client
  384. assert_equal "Microsoft", first_client.name
  385. assert_equal 1, firm.clients_using_sql.size
  386. assert_equal 1, Firm.find(:first).clients_using_sql.size
  387. end
  388. def test_counting_using_sql
  389. assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
  390. assert Firm.find(:first).clients_using_counter_sql.any?
  391. assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
  392. assert !Firm.find(:first).clients_using_zero_counter_sql.any?
  393. end
  394. def test_counting_non_existant_items_using_sql
  395. assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
  396. end
  397. def test_belongs_to_sanity
  398. c = Client.new
  399. assert_nil c.firm
  400. if c.firm
  401. assert false, "belongs_to failed if check"
  402. end
  403. unless c.firm
  404. else
  405. assert false, "belongs_to failed unless check"
  406. end
  407. end
  408. def test_find_ids
  409. firm = Firm.find(:first)
  410. assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }
  411. client = firm.clients.find(2)
  412. assert_kind_of Client, client
  413. client_ary = firm.clients.find([2])
  414. assert_kind_of Array, client_ary
  415. assert_equal client, client_ary.first
  416. client_ary = firm.clients.find(2, 3)
  417. assert_kind_of Array, client_ary
  418. assert_equal 2, client_ary.size
  419. assert_equal client, client_ary.first
  420. assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
  421. end
  422. def test_find_all
  423. firm = Firm.find(:first)
  424. assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
  425. assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
  426. end
  427. def test_find_all_sanitized
  428. firm = Firm.find(:first)
  429. summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
  430. assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
  431. assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
  432. end
  433. def test_find_first
  434. firm = Firm.find(:first)
  435. client2 = Client.find(2)
  436. assert_equal firm.clients.first, firm.clients.find(:first)
  437. assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
  438. end
  439. def test_find_first_sanitized
  440. firm = Firm.find(:first)
  441. client2 = Client.find(2)
  442. assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
  443. assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
  444. end
  445. def test_find_in_collection
  446. assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
  447. assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
  448. end
  449. def test_find_grouped
  450. all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1")
  451. grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count')
  452. assert_equal 2, all_clients_of_firm1.size
  453. assert_equal 1, grouped_clients_of_firm1.size
  454. end
  455. def test_adding
  456. force_signal37_to_load_all_clients_of_firm
  457. natural = Client.new("name" => "Natural Company")
  458. companies(:first_firm).clients_of_firm << natural
  459. assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
  460. assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
  461. assert_equal natural, companies(:first_firm).clients_of_firm.last
  462. end
  463. def test_adding_using_create
  464. first_firm = companies(:first_firm)
  465. assert_equal 2, first_firm.plain_clients.size
  466. natural = first_firm.plain_clients.create(:name => "Natural Company")
  467. assert_equal 3, first_firm.plain_clients.length
  468. assert_equal 3, first_firm.plain_clients.size
  469. end
  470. def test_create_with_bang_on_has_many_when_parent_is_new_raises
  471. assert_raises(ActiveRecord::RecordNotSaved) do
  472. firm = Firm.new
  473. firm.plain_clients.create! :name=>"Whoever"
  474. end
  475. end
  476. def test_regular_create_on_has_many_when_parent_is_new_raises
  477. assert_raises(ActiveRecord::RecordNotSaved) do
  478. firm = Firm.new
  479. firm.plain_clients.create :name=>"Whoever"
  480. end
  481. end
  482. def test_create_with_bang_on_habtm_when_parent_is_new_raises
  483. assert_raises(ActiveRecord::RecordNotSaved) do
  484. Developer.new("name" => "Aredridel").projects.create!
  485. end
  486. end
  487. def test_adding_a_mismatch_class
  488. assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
  489. assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
  490. assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
  491. end
  492. def test_adding_a_collection
  493. force_signal37_to_load_all_clients_of_firm
  494. companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
  495. assert_equal 3, companies(:first_firm).clients_of_firm.size
  496. assert_equal 3, companies(:first_firm).clients_of_firm(true).size
  497. end
  498. def test_adding_before_save
  499. no_of_firms = Firm.count
  500. no_of_clients = Client.count
  501. new_firm = Firm.new("name" => "A New Firm, Inc")
  502. c = Client.new("name" => "Apple")
  503. new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
  504. assert_equal 1, new_firm.clients_of_firm.size
  505. new_firm.clients_of_firm << c
  506. assert_equal 2, new_firm.clients_of_firm.size
  507. assert_equal no_of_firms, Firm.count # Firm was not saved to database.
  508. assert_equal no_of_clients, Client.count # Clients were not saved to database.
  509. assert new_firm.save
  510. assert !new_firm.new_record?
  511. assert !c.new_record?
  512. assert_equal new_firm, c.firm
  513. assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
  514. assert_equal no_of_clients+2, Client.count # Clients were saved to database.
  515. assert_equal 2, new_firm.clients_of_firm.size
  516. assert_equal 2, new_firm.clients_of_firm(true).size
  517. end
  518. def test_invalid_adding
  519. firm = Firm.find(1)
  520. assert !(firm.clients_of_firm << c = Client.new)
  521. assert c.new_record?
  522. assert !firm.valid?
  523. assert !firm.save
  524. assert c.new_record?
  525. end
  526. def test_invalid_adding_before_save
  527. no_of_firms = Firm.count
  528. no_of_clients = Client.count
  529. new_firm = Firm.new("name" => "A New Firm, Inc")
  530. new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
  531. assert c.new_record?
  532. assert !c.valid?
  533. assert !new_firm.valid?
  534. assert !new_firm.save
  535. assert c.new_record?
  536. assert new_firm.new_record?
  537. end
  538. def test_build
  539. new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
  540. assert_equal "Another Client", new_client.name
  541. assert new_client.new_record?
  542. assert_equal new_client, companies(:first_firm).clients_of_firm.last
  543. assert companies(:first_firm).save
  544. assert !new_client.new_record?
  545. assert_equal 2, companies(:first_firm).clients_of_firm(true).size
  546. end
  547. def test_build_many
  548. new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
  549. assert_equal 2, new_clients.size
  550. assert companies(:first_firm).save
  551. assert_equal 3, companies(:first_firm).clients_of_firm(true).size
  552. end
  553. def test_build_without_loading_association
  554. first_topic = topics(:first)
  555. Reply.column_names
  556. assert_equal 1, first_topic.replies.length
  557. assert_no_queries do
  558. first_topic.replies.build(:title => "Not saved", :content => "Superstars")
  559. assert_equal 2, first_topic.replies.size
  560. end
  561. assert_equal 2, first_topic.replies.to_ary.size
  562. end
  563. def test_create_without_loading_association
  564. first_firm = companies(:first_firm)
  565. Firm.column_names
  566. Client.column_names
  567. assert_equal 1, first_firm.clients_of_firm.size
  568. first_firm.clients_of_firm.reset
  569. assert_queries(1) do
  570. first_firm.clients_of_firm.create(:name => "Superstars")
  571. end
  572. assert_equal 2, first_firm.clients_of_firm.size
  573. end
  574. def test_invalid_build
  575. new_client = companies(:first_firm).clients_of_firm.build
  576. assert new_client.new_record?
  577. assert !new_client.valid?
  578. assert_equal new_client, companies(:first_firm).clients_of_firm.last
  579. assert !companies(:first_firm).save
  580. assert new_client.new_record?
  581. assert_equal 1, companies(:first_firm).clients_of_firm(true).size
  582. end
  583. def test_create
  584. force_signal37_to_load_all_clients_of_firm
  585. new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
  586. assert !new_client.new_record?
  587. assert_equal new_client, companies(:first_firm).clients_of_firm.last
  588. assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
  589. end
  590. def test_create_many
  591. companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
  592. assert_equal 3, companies(:first_firm).clients_of_firm(true).size
  593. end
  594. def test_find_or_initialize
  595. the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
  596. assert_equal companies(:first_firm).id, the_client.firm_id
  597. assert_equal "Yet another client", the_client.name
  598. assert the_client.new_record?
  599. end
  600. def test_find_or_create
  601. number_of_clients = companies(:first_firm).clients.size
  602. the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
  603. assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
  604. assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client")
  605. assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
  606. end
  607. def test_deleting
  608. force_signal37_to_load_all_clients_of_firm
  609. companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
  610. assert_equal 0, companies(:first_firm).clients_of_firm.size
  611. assert_equal 0, companies(:first_firm).clients_of_firm(true).size
  612. end
  613. def test_deleting_before_save
  614. new_firm = Firm.new("name" => "A New Firm, Inc.")
  615. new_client = new_firm.clients_of_firm.build("name" => "Another Client")
  616. assert_equal 1, new_firm.clients_of_firm.size
  617. new_firm.clients_of_firm.delete(new_client)
  618. assert_equal 0, new_firm.clients_of_firm.size
  619. end
  620. def test_deleting_a_collection
  621. force_signal37_to_load_all_clients_of_firm
  622. companies(:first_firm).clients_of_firm.create("name" => "Another Client")
  623. assert_equal 2, companies(:first_firm).clients_of_firm.size
  624. companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
  625. assert_equal 0, companies(:first_firm).clients_of_firm.size
  626. assert_equal 0, companies(:first_firm).clients_of_firm(true).size
  627. end
  628. def test_delete_all
  629. force_signal37_to_load_all_clients_of_firm
  630. companies(:first_firm).clients_of_firm.create("name" => "Another Client")
  631. assert_equal 2, companies(:first_firm).clients_of_firm.size
  632. companies(:first_firm).clients_of_firm.delete_all
  633. assert_equal 0, companies(:first_firm).clients_of_firm.size
  634. assert_equal 0, companies(:first_firm).clients_of_firm(true).size
  635. end
  636. def test_delete_all_with_not_yet_loaded_association_collection
  637. force_signal37_to_load_all_clients_of_firm
  638. companies(:first_firm).clients_of_firm.create("name" => "Another Client")
  639. assert_equal 2, companies(:first_firm).clients_of_firm.size
  640. companies(:first_firm).clients_of_firm.reset
  641. companies(:first_firm).clients_of_firm.delete_all
  642. assert_equal 0, companies(:first_firm).clients_of_firm.size
  643. assert_equal 0, companies(:first_firm).clients_of_firm(true).size
  644. end
  645. def test_clearing_an_association_collection
  646. firm = companies(:first_firm)
  647. client_id = firm.clients_of_firm.first.id
  648. assert_equal 1, firm.clients_of_firm.size
  649. firm.clients_of_firm.clear
  650. assert_equal 0, firm.clients_of_firm.size
  651. assert_equal 0, firm.clients_of_firm(true).size
  652. assert_equal [], Client.destroyed_client_ids[firm.id]
  653. # Should not be destroyed since the association is not dependent.
  654. assert_nothing_raised do
  655. assert Client.find(client_id).firm.nil?
  656. end
  657. end
  658. def test_clearing_a_dependent_association_collection
  659. firm = companies(:first_firm)
  660. client_id = firm.dependent_clients_of_firm.first.id
  661. assert_equal 1, firm.dependent_clients_of_firm.size
  662. # :dependent means destroy is called on each client
  663. firm.dependent_clients_of_firm.clear
  664. assert_equal 0, firm.dependent_clients_of_firm.size
  665. assert_equal 0, firm.dependent_clients_of_firm(true).size
  666. assert_equal [client_id], Client.destroyed_client_ids[firm.id]
  667. # Should be destroyed since the association is dependent.
  668. assert Client.find_by_id(client_id).nil?
  669. end
  670. def test_clearing_an_exclusively_dependent_association_collection
  671. firm = companies(:first_firm)
  672. client_id = firm.exclusively_dependent_clients_of_firm.first.id
  673. assert_equal 1, firm.exclusively_dependent_clients_of_firm.size
  674. assert_equal [], Client.destroyed_client_ids[firm.id]
  675. # :exclusively_dependent means each client is deleted directly from
  676. # the database without looping through them calling destroy.
  677. firm.exclusively_dependent_clients_of_firm.clear
  678. assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
  679. assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
  680. assert_equal [3], Client.destroyed_client_ids[firm.id]
  681. # Should be destroyed since the association is exclusively dependent.
  682. assert Client.find_by_id(client_id).nil?
  683. end
  684. def test_dependent_association_respects_optional_conditions_on_delete
  685. firm = companies(:odegy)
  686. Client.create(:client_of => firm.id, :name => "BigShot Inc.")
  687. Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
  688. # only one of two clients is included in the association due to the :conditions key
  689. assert_equal 2, Client.find_all_by_client_of(firm.id).size
  690. assert_equal 1, firm.dependent_conditional_clients_of_firm.size
  691. firm.destroy
  692. # only the correctly associated client should have been deleted
  693. assert_equal 1, Client.find_all_by_client_of(firm.id).size
  694. end
  695. def test_dependent_association_respects_optional_sanitized_conditions_on_delete
  696. firm = companies(:odegy)
  697. Client.create(:client_of => firm.id, :name => "BigShot Inc.")
  698. Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
  699. # only one of two clients is included in the association due to the :conditions key
  700. assert_equal 2, Client.find_all_by_client_of(firm.id).size
  701. assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
  702. firm.destroy
  703. # only the correctly associated client should have been deleted
  704. assert_equal 1, Client.find_all_by_client_of(firm.id).size
  705. end
  706. def test_clearing_without_initial_access
  707. firm = companies(:first_firm)
  708. firm.clients_of_firm.clear
  709. assert_equal 0, firm.clients_of_firm.size
  710. assert_equal 0, firm.clients_of_firm(true).size
  711. end
  712. def test_deleting_a_item_which_is_not_in_the_collection
  713. force_signal37_to_load_all_clients_of_firm
  714. summit = Client.find_by_name('Summit')
  715. companies(:first_firm).clients_of_firm.delete(summit)
  716. assert_equal 1, companies(:first_firm).clients_of_firm.size
  717. assert_equal 1, companies(:first_firm).clients_of_firm(true).size
  718. assert_equal 2, summit.client_of
  719. end
  720. def test_deleting_type_mismatch
  721. david = Developer.find(1)
  722. david.projects.reload
  723. assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
  724. end
  725. def test_deleting_self_type_mismatch
  726. david = Developer.find(1)
  727. david.projects.reload
  728. assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
  729. end
  730. def test_destroy_all
  731. force_signal37_to_load_all_clients_of_firm
  732. assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
  733. companies(:first_firm).clients_of_firm.destroy_all
  734. assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
  735. assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
  736. end
  737. def test_dependence
  738. firm = companies(:first_firm)
  739. assert_equal 2, firm.clients.size
  740. firm.destroy
  741. assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
  742. end
  743. def test_destroy_dependent_when_deleted_from_association
  744. firm = Firm.find(:first)
  745. assert_equal 2, firm.clients.size
  746. client = firm.clients.first
  747. firm.clients.delete(client)
  748. assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
  749. assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
  750. assert_equal 1, firm.clients.size
  751. end
  752. def test_three_levels_of_dependence
  753. topic = Topic.create "title" => "neat and simple"
  754. reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
  755. silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
  756. assert_nothing_raised { topic.destroy }
  757. end
  758. uses_transaction :test_dependence_with_transaction_support_on_failure
  759. def test_dependence_with_transaction_support_on_failure
  760. firm = companies(:first_firm)
  761. clients = firm.clients
  762. assert_equal 2, clients.length
  763. clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
  764. firm.destroy rescue "do nothing"
  765. assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
  766. end
  767. def test_dependence_on_account
  768. num_accounts = Account.count
  769. companies(:first_firm).destroy
  770. assert_equal num_accounts - 1, Account.count
  771. end
  772. def test_depends_and_nullify
  773. num_accounts = Account.count
  774. num_companies = Company.count
  775. core = companies(:rails_core)
  776. assert_equal accounts(:rails_core_account), core.account
  777. assert_equal companies(:leetsoft, :jadedpixel), core.companies
  778. core.destroy
  779. assert_nil accounts(:rails_core_account).reload.firm_id
  780. assert_nil companies(:leetsoft).reload.client_of
  781. assert_nil companies(:jadedpixel).reload.client_of
  782. assert_equal num_accounts, Account.count
  783. end
  784. def test_included_in_collection
  785. assert companies(:first_firm).clients.include?(Client.find(2))
  786. end
  787. def test_adding_array_and_collection
  788. assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
  789. end
  790. def test_find_all_without_conditions
  791. firm = companies(:first_firm)
  792. assert_equal 2, firm.clients.find(:all).length
  793. end
  794. def test_replace_with_less
  795. firm = Firm.find(:first)
  796. firm.clients = [companies(:first_client)]
  797. assert firm.save, "Could not save firm"
  798. firm.reload
  799. assert_equal 1, firm.clients.length
  800. end
  801. def test_replace_with_less_and_dependent_nullify
  802. num_companies = Company.count
  803. companies(:rails_core).companies = []
  804. assert_equal num_companies, Company.count
  805. end
  806. def test_replace_with_new
  807. firm = Firm.find(:first)
  808. firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
  809. firm.save
  810. firm.reload
  811. assert_equal 2, firm.clients.length
  812. assert !firm.clients.include?(:first_client)
  813. end
  814. def test_replace_on_new_object
  815. firm = Firm.new("name" => "New Firm")
  816. firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
  817. assert firm.save
  818. firm.reload
  819. assert_equal 2, firm.clients.length
  820. assert firm.clients.include?(Client.find_by_name("New Client"))
  821. end
  822. def test_get_ids
  823. assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
  824. end
  825. def test_assign_ids
  826. firm = Firm.new("name" => "Apple")
  827. firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
  828. firm.save
  829. firm.reload
  830. assert_equal 2, firm.clients.length
  831. assert firm.clients.include?(companies(:second_client))
  832. end
  833. def test_assign_ids_ignoring_blanks
  834. firm = Firm.create!(:name => 'Apple')
  835. firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
  836. firm.save!
  837. assert_equal 2, firm.clients(true).size
  838. assert firm.clients.include?(companies(:second_client))
  839. end
  840. def test_get_ids_for_through
  841. assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
  842. end
  843. def test_assign_ids_for_through
  844. assert_raise(NoMethodError) { authors(:mary).comment_ids = [123] }
  845. end
  846. end
  847. class BelongsToAssociationsTest < Test::Unit::TestCase
  848. fixtures :accounts, :companies, :developers, :projects, :topics,
  849. :developers_projects, :computers, :authors, :posts, :tags, :taggings
  850. def test_belongs_to
  851. Client.find(3).firm.name
  852. assert_equal companies(:first_firm).name, Client.find(3).firm.name
  853. assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
  854. end
  855. def test_proxy_assignment
  856. account = Account.find(1)
  857. assert_nothing_raised { account.firm = account.firm }
  858. end
  859. def test_triple_equality
  860. assert Client.find(3).firm === Firm
  861. assert Firm === Client.find(3).firm
  862. end
  863. def test_type_mismatch
  864. assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
  865. assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
  866. end
  867. def test_natural_assignment
  868. apple = Firm.create("name" => "Apple")
  869. citibank = Account.create("credit_limit" => 10)
  870. citibank.firm = apple
  871. assert_equal apple.id, citibank.firm_id
  872. end
  873. def test_no_unexpected_aliasing
  874. first_firm = companies(:first_firm)
  875. another_firm = companies(:another_firm)
  876. citibank = Account.create("credit_limit" => 10)
  877. citibank.firm = first_firm
  878. original_proxy = citibank.firm
  879. citibank.firm = another_firm
  880. assert_equal first_firm.object_id, original_proxy.object_id
  881. assert_equal another_firm.object_id, citibank.firm.object_id
  882. end
  883. def test_creating_the_belonging_object
  884. citibank = Account.create("credit_limit" => 10)
  885. apple = citibank.create_firm("name" => "Apple")
  886. assert_equal apple, citibank.firm
  887. citibank.save
  888. citibank.reload
  889. assert_equal apple, citibank.firm
  890. end
  891. def test_building_the_belonging_object
  892. citibank = Account.create("credit_limit" => 10)
  893. apple = citibank.build_firm("name" => "Apple")
  894. citibank.save
  895. assert_equal apple.id, citibank.firm_id
  896. end
  897. def test_natural_assignment_to_nil
  898. client = Client.find(3)
  899. client.firm = nil
  900. client.save
  901. assert_nil client.firm(true)
  902. assert_nil client.client_of
  903. end
  904. def test_with_different_class_name
  905. assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
  906. assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
  907. end
  908. def test_with_condition
  909. assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
  910. assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
  911. end
  912. def test_belongs_to_counter
  913. debate = Topic.create("title" => "debate")
  914. assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
  915. trash = debate.replies.create("title" => "blah!", "content" => "world around!")
  916. assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
  917. trash.destroy
  918. assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
  919. end
  920. def test_belongs_to_counter_with_reassigning
  921. t1 = Topic.create("title" => "t1")
  922. t2 = Topic.create("title" => "t2")
  923. r1 = Reply.new("title" => "r1", "content" => "r1")
  924. r1.topic = t1
  925. assert r1.save
  926. assert_equal 1, Topic.find(t1.id).replies.size
  927. assert_equal 0, Topic.find(t2.id).replies.size
  928. r1.topic = Topic.find(t2.id)
  929. assert r1.save
  930. assert_equal 0, Topic.find(t1.id).replies.size
  931. assert_equal 1, Topic.find(t2.id).replies.size
  932. r1.topic = nil
  933. assert_equal 0, Topic.find(t1.id).replies.size
  934. assert_equal 0, Topic.find(t2.id).replies.size
  935. r1.topic = t1
  936. assert_equal 1, Topic.find(t1.id).replies.size
  937. assert_equal 0, Topic.find(t2.id).replies.size
  938. r1.destroy
  939. assert_equal 0, Topic.find(t1.id).replies.size
  940. assert_equal 0, Topic.find(t2.id).replies.size
  941. end
  942. def test_belongs_to_counter_after_save
  943. topic = Topic.create!(:title => "monday night")
  944. topic.replies.create!(:title => "re: monday night", :content => "football")
  945. assert_equal 1, Topic.find(topic.id)[:replies_count]
  946. topic.save!
  947. assert_equal 1, Topic.find(topic.id)[:replies_count]
  948. end
  949. def test_belongs_to_counter_after_update_attributes
  950. topic = Topic.create!(:title => "37s")
  951. topic.replies.create!(:title => "re: 37s", :content => "rails")
  952. assert_equal 1, Topic.find(topic.id)[:replies_count]
  953. topic.update_attributes(:title => "37signals")
  954. assert_equal 1, Topic.find(topic.id)[:replies_count]
  955. end
  956. def test_belongs_to_counter_after_save
  957. topic = Topic.create("title" => "monday night")
  958. topic.replies.create("title" => "re: monday night", "content" => "football")
  959. assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
  960. topic.save
  961. assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
  962. end
  963. def test_belongs_to_counter_after_update_attributes
  964. topic = Topic.create("title" => "37s")
  965. topic.replies.create("title" => "re: 37s", "content" => "rails")
  966. assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
  967. topic.update_attributes("title" => "37signals")
  968. assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
  969. end
  970. def test_assignment_before_parent_saved
  971. client = Client.find(:first)
  972. apple = Firm.new("name" => "Apple")
  973. client.firm = apple
  974. assert_equal apple, client.firm
  975. assert apple.new_record?
  976. assert client.save
  977. assert apple.save
  978. assert !apple.new_record?
  979. assert_equal apple, client.firm
  980. assert_equal apple, client.firm(true)
  981. end
  982. def test_assignment_before_child_saved
  983. final_cut = Client.new("name" => "Final Cut")
  984. firm = Firm.find(1)
  985. final_cut.firm = firm
  986. assert final_cut.new_record?
  987. assert final_cut.save
  988. assert !final_cut.new_record?
  989. assert !firm.new_record?
  990. assert_equal firm, final_cut.firm
  991. assert_equal firm, final_cut.firm(true)
  992. end
  993. def test_assignment_before_either_saved
  994. final_cut = Client.new("name" => "Final Cut")
  995. apple = Firm.new("name" => "Apple")
  996. final_cut.firm = apple
  997. assert final_cut.new_record?
  998. assert apple.new_record?
  999. assert final_cut.save
  1000. assert !final_cut.new_record?
  1001. assert !apple.new_record?
  1002. assert_equal apple, final_cut.firm
  1003. assert_equal apple, final_cut.firm(true)
  1004. end
  1005. def test_new_record_with_foreign_key_but_no_object
  1006. c = Client.new("firm_id" => 1)
  1007. assert_equal Firm.find(:first), c.firm_with_basic_id
  1008. end
  1009. def test_forgetting_the_load_when_foreign_key_enters_late
  1010. c = Client.new
  1011. assert_nil c.firm_with_basic_id
  1012. c.firm_id = 1
  1013. assert_equal Firm.find(:first), c.firm_with_basic_id
  1014. end
  1015. def test_field_name_same_as_foreign_key
  1016. computer = Computer.find(1)
  1017. assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
  1018. end
  1019. def test_counter_cache
  1020. topic = Topic.create :title => "Zoom-zoom-zoom"
  1021. assert_equal 0, topic[:replies_count]
  1022. reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
  1023. reply.topic = topic
  1024. assert_equal 1, topic.reload[:replies_count]
  1025. assert_equal 1, topic.replies.size
  1026. topic[:replies_count] = 15
  1027. assert_equal 15, topic.replies.size
  1028. end
  1029. def test_custom_counter_cache
  1030. reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
  1031. assert_equal 0, reply[:replies_count]
  1032. silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
  1033. silly.reply = reply
  1034. assert_equal 1, reply.reload[:replies_count]
  1035. assert_equal 1, reply.replies.size
  1036. reply[:replies_count] = 17
  1037. assert_equal 17, reply.replies.size
  1038. end
  1039. def test_store_two_association_with_one_save
  1040. num_orders = Order.count
  1041. num_customers = Customer.count
  1042. order = Order.new
  1043. customer1 = order.billing = Customer.new
  1044. customer2 = order.shipping = Customer.new
  1045. assert order.save
  1046. assert_equal customer1, order.billing
  1047. assert_equal customer2, order.shipping
  1048. order.reload
  1049. assert_equal customer1, order.billing
  1050. assert_equal customer2, order.shipping
  1051. assert_equal num_orders +1, Order.count
  1052. assert_equal num_customers +2, Customer.count
  1053. end
  1054. def test_store_association_in_two_relations_with_one_save
  1055. num_orders = Order.count
  1056. num_customers = Customer.count
  1057. order = Order.new
  1058. customer = order.billing = order.shipping = Customer.new
  1059. assert order.save
  1060. assert_equal customer, order.billing
  1061. assert_equal customer, order.shipping
  1062. order.reload
  1063. assert_equal customer, order.billing
  1064. assert_equal customer, order.shipping
  1065. assert_equal num_orders +1, Order.count
  1066. assert_equal num_customers +1, Customer.count
  1067. end
  1068. def test_store_association_in_two_relations_with_one_save_in_existing_object
  1069. num_orders = Order.count
  1070. num_customers = Customer.count
  1071. order = Order.create
  1072. customer = order.billing = order.shipping = Customer.new
  1073. assert order.save
  1074. assert_equal customer, order.billing
  1075. assert_equal customer, order.shipping
  1076. order.reload
  1077. assert_equal customer, order.billing
  1078. assert_equal customer, order.shipping
  1079. assert_equal num_orders +1, Order.count
  1080. assert_equal num_customers +1, Customer.count
  1081. end
  1082. def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
  1083. num_orders = Order.count
  1084. num_customers = Customer.count
  1085. order = Order.create
  1086. customer = order.billing = order.shipping = Customer.new
  1087. assert order.save
  1088. assert_equal customer, order.billing
  1089. assert_equal customer, order.shipping
  1090. order.reload
  1091. customer = order.billing = order.shipping = Customer.new
  1092. assert order.save
  1093. order.reload
  1094. assert_equal customer, order.billing
  1095. assert_equal customer, order.shipping
  1096. assert_equal num_orders +1, Order.count
  1097. assert_equal num_customers +2, Customer.count
  1098. end
  1099. def test_association_assignment_sticks
  1100. post = Post.find(:first)
  1101. author1, author2 = Author.find(:all, :limit => 2)
  1102. assert_not_nil author1
  1103. assert_not_nil author2
  1104. # make sure the association is loaded
  1105. post.author
  1106. # set the association by id, directly
  1107. post.author_id = author2.id
  1108. # save and reload
  1109. post.save!
  1110. post.reload
  1111. # the author id of the post should be the id we set
  1112. assert_equal post.author_id, author2.id
  1113. end
  1114. end
  1115. class ProjectWithAfterCreateHook < ActiveRecord::Base
  1116. set_table_name 'projects'
  1117. has_and_belongs_to_many :developers,
  1118. :class_name => "DeveloperForProjectWithAfterCreateHook",
  1119. :join_table => "developers_projects",
  1120. :foreign_key => "project_id",
  1121. :association_foreign_key => "developer_id"
  1122. after_create :add_david
  1123. def add_david
  1124. david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
  1125. david.projects << self
  1126. end
  1127. end
  1128. class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
  1129. set_table_name 'developers'
  1130. has_and_belongs_to_many :projects,
  1131. :class_name => "ProjectWithAfterCreateHook",
  1132. :join_table => "developers_projects",
  1133. :association_foreign_key => "project_id",
  1134. :foreign_key => "developer_id"
  1135. end
  1136. class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
  1137. fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects
  1138. def test_has_and_belongs_to_many
  1139. david = Developer.find(1)
  1140. assert !david.projects.empty?
  1141. assert_equal 2, david.projects.size
  1142. active_record = Project.find(1)
  1143. assert !active_record.developers.empty?
  1144. assert_equal 3, active_record.developers.size
  1145. assert active_record.developers.include?(david)
  1146. end
  1147. def test_triple_equality
  1148. assert !(Array === Developer.find(1).projects)
  1149. assert Developer.find(1).projects === Array
  1150. end
  1151. def test_adding_single
  1152. jamis = Developer.find(2)
  1153. jamis.projects.reload # causing the collection to load
  1154. action_controller = Project.find(2)
  1155. assert_equal 1, jamis.projects.size
  1156. assert_equal 1, action_controller.developers.size
  1157. jamis.projects << action_controller
  1158. assert_equal 2, jamis.projects.size
  1159. assert_equal 2, jamis.projects(true).size
  1160. assert_equal 2, action_controller.developers(true).size
  1161. end
  1162. def test_adding_type_mismatch
  1163. jamis = Developer.find(2)
  1164. assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
  1165. assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
  1166. end
  1167. def test_adding_from_the_project
  1168. jamis = Developer.find(2)
  1169. action_controller = Project.find(2)
  1170. action_controller.developers.reload
  1171. assert_equal 1, jamis.projects.size
  1172. assert_equal 1, action_controller.developers.size
  1173. action_controller.developers << jamis
  1174. assert_equal 2, jamis.projects(true).size
  1175. assert_equal 2, action_controller.developers.size
  1176. assert_equal 2, action_controller.developers(true).size
  1177. end
  1178. def test_adding_from_the_project_fixed_timestamp
  1179. jamis = Developer.find(2)
  1180. action_controller = Project.find(2)
  1181. action_controller.developers.reload
  1182. assert_equal 1, jamis.projects.size
  1183. assert_equal 1, action_controller.developers.size
  1184. updated_at = jamis.updated_at
  1185. action_controller.developers << jamis
  1186. assert_equal updated_at, jamis.updated_at
  1187. assert_equal 2, jamis.projects(true).size
  1188. assert_equal 2, action_controller.developers.size
  1189. assert_equal 2, action_controller.developers(true).size
  1190. end
  1191. def test_adding_multiple
  1192. aredridel = Developer.new("name" => "Aredridel")
  1193. aredridel.save
  1194. aredridel.projects.reload
  1195. aredridel.projects.push(Project.find(1), Project.find(2))
  1196. assert_equal 2, aredridel.projects.size
  1197. assert_equal 2, aredridel.projects(true).size
  1198. end
  1199. def test_adding_a_collection
  1200. aredridel = Developer.new("name" => "Aredridel")
  1201. aredridel.save
  1202. aredridel.projects.reload
  1203. aredridel.projects.concat([Project.find(1), Project.find(2)])
  1204. assert_equal 2, aredridel.projects.size
  1205. assert_equal 2, aredridel.projects(true).size
  1206. end
  1207. def test_adding_uses_default_values_on_join_table
  1208. ac = projects(:action_controller)
  1209. assert !developers(:jamis).projects.include?(ac)
  1210. developers(:jamis).projects << ac
  1211. assert developers(:jamis, :reload).projects.include?(ac)
  1212. project = developers(:jamis).projects.detect { |p| p == ac }
  1213. assert_equal 1, project.access_level.to_i
  1214. end
  1215. def test_habtm_attribute_access_and_respond_to
  1216. project = developers(:jamis).projects[0]
  1217. assert project.has_attribute?("name")
  1218. assert project.has_attribute?("joined_on")
  1219. assert project.has_attribute?("access_level")
  1220. assert project.respond_to?("name")
  1221. assert project.respond_to?

Large files files are truncated, but you can click here to view the full file