PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://monkeycharger.googlecode.com/
Ruby | 1846 lines | 1548 code | 280 blank | 18 comment | 4 complexity | bb18ae71cf9c7e928c0bdca0d7b58047 MD5 | raw file

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

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