PageRenderTime 64ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/millbanksystems/hansard
Ruby | 1880 lines | 1579 code | 287 blank | 14 comment | 7 complexity | 8fff5036ea3996e199dc3ee02d12bcae MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0-no-copyleft-exception

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

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