associations_test.rb 40.2 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1 2 3 4 5 6
require 'abstract_unit'
require 'fixtures/developer'
require 'fixtures/project'
require 'fixtures/company'
require 'fixtures/topic'
require 'fixtures/reply'
7
require 'fixtures/computer'
8 9
require 'fixtures/customer'
require 'fixtures/order'
D
Initial  
David Heinemeier Hansson 已提交
10 11 12 13 14 15 16 17 18 19 20 21

# Can't declare new classes in test case methods, so tests before that
bad_collection_keys = false
begin
  class Car < ActiveRecord::Base; has_many :wheels, :name => "wheels"; end
rescue ActiveRecord::ActiveRecordError
  bad_collection_keys = true
end
raise "ActiveRecord should have barked on bad collection keys" unless bad_collection_keys


class AssociationsTest < Test::Unit::TestCase
22 23
  fixtures :accounts, :companies, :developers, :projects, :developers_projects,
           :computers
D
Initial  
David Heinemeier Hansson 已提交
24 25
  
  def test_force_reload
26
    firm = Firm.new("name" => "A New Firm, Inc")
D
Initial  
David Heinemeier Hansson 已提交
27 28 29 30 31 32
    firm.save
    firm.clients.each {|c|} # forcing to load all clients
    assert firm.clients.empty?, "New firm shouldn't have client objects"
    assert !firm.has_clients?, "New firm shouldn't have clients"
    assert_equal 0, firm.clients.size, "New firm should have 0 clients"

33
    client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
D
Initial  
David Heinemeier Hansson 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    client.save

    assert firm.clients.empty?, "New firm should have cached no client objects"
    assert !firm.has_clients?, "New firm should have cached a no-clients response"
    assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"

    assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
    assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count"
  end

  def test_storing_in_pstore
    require "tmpdir"
    store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
    File.delete(store_filename) if File.exists?(store_filename)
    require "pstore"
    apple = Firm.create("name" => "Apple")
    natural = Client.new("name" => "Natural Company")
    apple.clients << natural

    db = PStore.new(store_filename)
    db.transaction do
      db["apple"] = apple
    end

    db = PStore.new(store_filename)
    db.transaction do
      assert_equal "Natural Company", db["apple"].clients.first.name
    end
  end
end

class HasOneAssociationsTest < Test::Unit::TestCase
66
  fixtures :accounts, :companies, :developers, :projects, :developers_projects
D
Initial  
David Heinemeier Hansson 已提交
67 68
  
  def test_has_one
69 70
    assert_equal companies(:first_firm).account, Account.find(1)
    assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
D
Initial  
David Heinemeier Hansson 已提交
71 72
  end

73
  def test_triple_equality
74
    assert Account === companies(:first_firm).account
75 76
  end

D
Initial  
David Heinemeier Hansson 已提交
77
  def test_type_mismatch
78 79
    assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
    assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
D
Initial  
David Heinemeier Hansson 已提交
80 81 82 83 84 85 86 87 88 89
  end

  def test_natural_assignment
    apple = Firm.create("name" => "Apple")
    citibank = Account.create("credit_limit" => 10)
    apple.account = citibank
    assert_equal apple.id, citibank.firm_id
  end
  
  def test_natural_assignment_to_nil
90 91 92 93
    old_account_id = companies(:first_firm).account.id
    companies(:first_firm).account = nil
    companies(:first_firm).save
    assert_nil companies(:first_firm).account
94 95
    # account is dependent, therefore is destroyed when reference to owner is lost
    assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) } 
D
Initial  
David Heinemeier Hansson 已提交
96
  end
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  
  def test_assignment_without_replacement
    apple = Firm.create("name" => "Apple")
    citibank = Account.create("credit_limit" => 10)
    apple.account = citibank
    assert_equal apple.id, citibank.firm_id
    
    hsbc = apple.build_account({ :credit_limit => 20}, false)
    assert_equal apple.id, hsbc.firm_id
    hsbc.save
    assert_equal apple.id, citibank.firm_id

    nykredit = apple.create_account({ :credit_limit => 30}, false)
    assert_equal apple.id, nykredit.firm_id
    assert_equal apple.id, citibank.firm_id
    assert_equal apple.id, hsbc.firm_id
  end

  def test_assignment_without_replacement_on_create
    apple = Firm.create("name" => "Apple")
    citibank = Account.create("credit_limit" => 10)
    apple.account = citibank
    assert_equal apple.id, citibank.firm_id
    
121
    hsbc = apple.create_account({:credit_limit => 10}, false)
122 123 124 125
    assert_equal apple.id, hsbc.firm_id
    hsbc.save
    assert_equal apple.id, citibank.firm_id
  end
D
Initial  
David Heinemeier Hansson 已提交
126

127 128 129 130
  def test_dependence
    firm = Firm.find(1)
    assert !firm.account.nil?
    firm.destroy
131
    assert_equal 1, Account.count
132 133
  end

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
  def test_succesful_build_association
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save

    account = firm.build_account("credit_limit" => 1000)
    assert account.save
    assert_equal account, firm.account
  end

  def test_failing_build_association
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save

    account = firm.build_account
    assert !account.save
    assert_equal "can't be empty", account.errors.on("credit_limit")
  end

  def test_create_association
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save
    assert_equal firm.create_account("credit_limit" => 1000), firm.account
  end

D
Initial  
David Heinemeier Hansson 已提交
158 159 160
  def test_build
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save
161

162
    firm.account = account = Account.new("credit_limit" => 1000)
163
    assert_equal account, firm.account
D
Initial  
David Heinemeier Hansson 已提交
164 165 166 167
    assert account.save
    assert_equal account, firm.account
  end

168 169 170 171 172 173 174 175 176 177 178 179 180 181
  def test_build_before_child_saved
    firm = Firm.find(1)

    account = firm.account.build("credit_limit" => 1000)
    assert_equal account, firm.account
    assert account.new_record?
    assert firm.save
    assert_equal account, firm.account
    assert !account.new_record?
  end

  def test_build_before_either_saved
    firm = Firm.new("name" => "GlobalMegaCorp")

182
    firm.account = account = Account.new("credit_limit" => 1000)
183 184 185 186 187 188 189
    assert_equal account, firm.account
    assert account.new_record?
    assert firm.save
    assert_equal account, firm.account
    assert !account.new_record?
  end

D
Initial  
David Heinemeier Hansson 已提交
190 191 192 193
  def test_failing_build_association
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save
    
194
    firm.account = account = Account.new
195
    assert_equal account, firm.account
D
Initial  
David Heinemeier Hansson 已提交
196
    assert !account.save
197
    assert_equal account, firm.account
D
Initial  
David Heinemeier Hansson 已提交
198 199 200 201 202 203
    assert_equal "can't be empty", account.errors.on("credit_limit")
  end

  def test_create
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.save
204 205
    firm.account = account = Account.create("credit_limit" => 1000)
    assert_equal account, firm.account
D
Initial  
David Heinemeier Hansson 已提交
206
  end
207 208 209

  def test_create_before_save
    firm = Firm.new("name" => "GlobalMegaCorp")
210 211
    firm.account = account = Account.create("credit_limit" => 1000)
    assert_equal account, firm.account
D
Initial  
David Heinemeier Hansson 已提交
212 213 214 215
  end

  def test_dependence_with_missing_association
    Account.destroy_all
216 217
    firm = Firm.find(1)
    assert firm.account.nil?
D
Initial  
David Heinemeier Hansson 已提交
218 219
    firm.destroy
  end
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

  def test_assignment_before_parent_saved
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.account = a = Account.find(1)
    assert firm.new_record?
    assert_equal a, firm.account
    assert firm.save
    assert_equal a, firm.account
    assert_equal a, firm.account(true)
  end

  def test_assignment_before_child_saved
    firm = Firm.find(1)
    firm.account = a = Account.new("credit_limit" => 1000)
    assert !a.new_record?
    assert_equal a, firm.account
    assert_equal a, firm.account
    assert_equal a, firm.account(true)
  end

  def test_assignment_before_either_saved
    firm = Firm.new("name" => "GlobalMegaCorp")
    firm.account = a = Account.new("credit_limit" => 1000)
    assert firm.new_record?
    assert a.new_record?
    assert_equal a, firm.account
    assert firm.save
    assert !firm.new_record?
    assert !a.new_record?
    assert_equal a, firm.account
    assert_equal a, firm.account(true)
  end
D
Initial  
David Heinemeier Hansson 已提交
252 253 254 255
end


class HasManyAssociationsTest < Test::Unit::TestCase
256 257
  fixtures :accounts, :companies, :developers, :projects,
           :developers_projects, :topics
D
Initial  
David Heinemeier Hansson 已提交
258 259
  
  def force_signal37_to_load_all_clients_of_firm
260
    companies(:first_firm).clients_of_firm.each {|f| }
D
Initial  
David Heinemeier Hansson 已提交
261 262
  end
  
263
  def test_counting
264
    assert_equal 2, Firm.find(:first).clients.count
265 266
  end
  
D
Initial  
David Heinemeier Hansson 已提交
267
  def test_finding
268
    assert_equal 2, Firm.find(:first).clients.length
D
Initial  
David Heinemeier Hansson 已提交
269 270 271
  end

  def test_finding_default_orders
272
    assert_equal "Summit", Firm.find(:first).clients.first.name
D
Initial  
David Heinemeier Hansson 已提交
273 274 275
  end

  def test_finding_with_different_class_name_and_order
276
    assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
D
Initial  
David Heinemeier Hansson 已提交
277 278 279
  end

  def test_finding_with_foreign_key
280
    assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
D
Initial  
David Heinemeier Hansson 已提交
281 282 283
  end

  def test_finding_with_condition
284
    assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
D
Initial  
David Heinemeier Hansson 已提交
285 286 287
  end

  def test_finding_using_sql
288
    firm = Firm.find(:first)
D
Initial  
David Heinemeier Hansson 已提交
289 290 291 292
    first_client = firm.clients_using_sql.first
    assert_not_nil first_client
    assert_equal "Microsoft", first_client.name
    assert_equal 1, firm.clients_using_sql.size
293
    assert_equal 1, Firm.find(:first).clients_using_sql.size
D
Initial  
David Heinemeier Hansson 已提交
294 295
  end

296
  def test_counting_using_sql
297 298
    assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
    assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
299
  end
300 301

  def test_counting_non_existant_items_using_sql
302
    assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
303
  end
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
  
  def test_belongs_to_sanity
    c = Client.new
    assert_nil c.firm

    if c.firm
      assert false, "belongs_to failed if check"
    end

    unless c.firm
    else
      assert false,  "belongs_to failed unless check"
    end
        
  end
319

320
  def test_find_ids
321
    firm = Firm.find(:first)
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339

    assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }

    client = firm.clients.find(2)
    assert_kind_of Client, client

    client_ary = firm.clients.find([2])
    assert_kind_of Array, client_ary
    assert_equal client, client_ary.first

    client_ary = firm.clients.find(2, 3)
    assert_kind_of Array, client_ary
    assert_equal 2, client_ary.size
    assert_equal client, client_ary.first

    assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
  end

D
Initial  
David Heinemeier Hansson 已提交
340
  def test_find_all
341 342
    firm = Firm.find_first
    assert_equal firm.clients, firm.clients.find_all
343 344
    assert_equal 2, firm.clients.find(:all, :conditions => "type = 'Client'").length
    assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
D
Initial  
David Heinemeier Hansson 已提交
345 346 347 348 349
  end

  def test_find_all_sanitized
    firm = Firm.find_first
    assert_equal firm.clients.find_all("name = 'Summit'"), firm.clients.find_all(["name = '%s'", "Summit"])
350 351 352
    summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
    assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
    assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
D
Initial  
David Heinemeier Hansson 已提交
353 354
  end

355 356
  def test_find_first
    firm = Firm.find_first
357
    client2 = Client.find(2)
358
    assert_equal firm.clients.first, firm.clients.find_first
359 360
    assert_equal client2, firm.clients.find_first("type = 'Client'")
    assert_equal client2, firm.clients.find(:first, :conditions => "type = 'Client'")
361 362 363
  end

  def test_find_first_sanitized
364 365 366 367 368
    firm = Firm.find_first
    client2 = Client.find(2)
    assert_equal client2, firm.clients.find_first(["type = ?", "Client"])
    assert_equal client2, firm.clients.find(:first, :conditions => ['type = ?', 'Client'])
    assert_equal client2, firm.clients.find(:first, :conditions => ['type = :type', { :type => 'Client' }])
369 370
  end

D
Initial  
David Heinemeier Hansson 已提交
371
  def test_find_in_collection
372 373
    assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
    assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
D
Initial  
David Heinemeier Hansson 已提交
374 375 376 377 378
  end

  def test_adding
    force_signal37_to_load_all_clients_of_firm
    natural = Client.new("name" => "Natural Company")
379 380 381 382
    companies(:first_firm).clients_of_firm << natural
    assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
    assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
    assert_equal natural, companies(:first_firm).clients_of_firm.last
D
Initial  
David Heinemeier Hansson 已提交
383 384 385
  end
  
  def test_adding_a_mismatch_class
386 387 388
    assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
    assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
    assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
D
Initial  
David Heinemeier Hansson 已提交
389 390 391 392
  end
  
  def test_adding_a_collection
    force_signal37_to_load_all_clients_of_firm
393 394 395
    companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
    assert_equal 3, companies(:first_firm).clients_of_firm.size
    assert_equal 3, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
396 397
  end

398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
  def test_adding_before_save
    no_of_firms = Firm.count
    no_of_clients = Client.count
    new_firm = Firm.new("name" => "A New Firm, Inc")
    new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
    new_firm.clients_of_firm << (c = Client.new("name" => "Apple"))
    assert new_firm.new_record?
    assert c.new_record?
    assert_equal 2, new_firm.clients_of_firm.size
    assert_equal no_of_firms, Firm.count      # Firm was not saved to database.
    assert_equal no_of_clients, Client.count  # Clients were not saved to database.
    assert new_firm.save
    assert !new_firm.new_record?
    assert !c.new_record?
    assert_equal new_firm, c.firm
    assert_equal no_of_firms+1, Firm.count      # Firm was saved to database.
    assert_equal no_of_clients+2, Client.count  # Clients were saved to database.
    assert_equal 2, new_firm.clients_of_firm.size
    assert_equal 2, new_firm.clients_of_firm(true).size
  end

  def test_invalid_adding
    firm = Firm.find(1)
    assert !(firm.clients_of_firm << c = Client.new)
    assert c.new_record?
    assert !firm.save
    assert c.new_record?
  end

  def test_invalid_adding_before_save
    no_of_firms = Firm.count
    no_of_clients = Client.count
    new_firm = Firm.new("name" => "A New Firm, Inc")
    new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
    assert c.new_record?
    assert !c.valid?
    assert new_firm.valid?
    assert !new_firm.save
    assert c.new_record?
    assert new_firm.new_record?
  end

D
Initial  
David Heinemeier Hansson 已提交
440
  def test_build
441
    new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
D
Initial  
David Heinemeier Hansson 已提交
442
    assert_equal "Another Client", new_client.name
443
    assert new_client.new_record?
444 445
    assert_equal new_client, companies(:first_firm).clients_of_firm.last
    assert companies(:first_firm).save
446
    assert !new_client.new_record?
447
    assert_equal 2, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
448
  end
449

450
  def test_build_many
451
    new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
452 453
    assert_equal 2, new_clients.size

454 455
    assert companies(:first_firm).save
    assert_equal 3, companies(:first_firm).clients_of_firm(true).size
456 457
  end

458
  def test_invalid_build
459
    new_client = companies(:first_firm).clients_of_firm.build
460 461
    assert new_client.new_record?
    assert !new_client.valid?
462 463
    assert_equal new_client, companies(:first_firm).clients_of_firm.last
    assert !companies(:first_firm).save
464
    assert new_client.new_record?
465
    assert_equal 1, companies(:first_firm).clients_of_firm(true).size
466
  end
D
Initial  
David Heinemeier Hansson 已提交
467 468 469
  
  def test_create
    force_signal37_to_load_all_clients_of_firm
470
    new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
471
    assert !new_client.new_record?
472 473
    assert_equal new_client, companies(:first_firm).clients_of_firm.last
    assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
D
Initial  
David Heinemeier Hansson 已提交
474
  end
475 476
  
  def test_create_many
477 478
    companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
    assert_equal 3, companies(:first_firm).clients_of_firm(true).size
479
  end
D
Initial  
David Heinemeier Hansson 已提交
480 481 482

  def test_deleting
    force_signal37_to_load_all_clients_of_firm
483 484 485
    companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
    assert_equal 0, companies(:first_firm).clients_of_firm.size
    assert_equal 0, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
486 487
  end

488 489 490 491 492 493 494 495
  def test_deleting_before_save
    new_firm = Firm.new("name" => "A New Firm, Inc.")
    new_client = new_firm.clients_of_firm.build("name" => "Another Client")
    assert_equal 1, new_firm.clients_of_firm.size
    new_firm.clients_of_firm.delete(new_client)
    assert_equal 0, new_firm.clients_of_firm.size
  end

D
Initial  
David Heinemeier Hansson 已提交
496 497
  def test_deleting_a_collection
    force_signal37_to_load_all_clients_of_firm
498 499 500 501 502 503
    companies(:first_firm).clients_of_firm.create("name" => "Another Client")
    assert_equal 2, companies(:first_firm).clients_of_firm.size
    #companies(:first_firm).clients_of_firm.clear
    companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
    assert_equal 0, companies(:first_firm).clients_of_firm.size
    assert_equal 0, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
504 505 506 507
  end

  def test_deleting_a_association_collection
    force_signal37_to_load_all_clients_of_firm
508 509 510 511 512
    companies(:first_firm).clients_of_firm.create("name" => "Another Client")
    assert_equal 2, companies(:first_firm).clients_of_firm.size
    companies(:first_firm).clients_of_firm.clear
    assert_equal 0, companies(:first_firm).clients_of_firm.size
    assert_equal 0, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
513 514 515 516 517
  end

  def test_deleting_a_item_which_is_not_in_the_collection
    force_signal37_to_load_all_clients_of_firm
    summit = Client.find_first("name = 'Summit'")
518 519 520
    companies(:first_firm).clients_of_firm.delete(summit)
    assert_equal 1, companies(:first_firm).clients_of_firm.size
    assert_equal 1, companies(:first_firm).clients_of_firm(true).size
D
Initial  
David Heinemeier Hansson 已提交
521 522 523 524 525
    assert_equal 2, summit.client_of
  end

  def test_deleting_type_mismatch
    david = Developer.find(1)
526
    david.projects.reload
D
Initial  
David Heinemeier Hansson 已提交
527 528 529 530 531
    assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
  end

  def test_deleting_self_type_mismatch
    david = Developer.find(1)
532
    david.projects.reload
D
Initial  
David Heinemeier Hansson 已提交
533 534 535 536 537
    assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
  end

  def test_destroy_all
    force_signal37_to_load_all_clients_of_firm
538 539 540 541
    assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
    companies(:first_firm).clients_of_firm.destroy_all
    assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
    assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
D
Initial  
David Heinemeier Hansson 已提交
542 543 544
  end

  def test_dependence
545 546 547 548
    firm = companies(:first_firm)
    assert_equal 2, firm.clients.size
    firm.destroy
    assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
549 550 551
  end

  def test_destroy_dependent_when_deleted_from_association
552
    firm = Firm.find(:first)
553 554 555 556 557 558 559 560
    assert_equal 2, firm.clients.size

    client = firm.clients.first
    firm.clients.delete(client)

    assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
    assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
    assert_equal 1, firm.clients.size
D
Initial  
David Heinemeier Hansson 已提交
561 562
  end

563 564 565 566 567 568 569 570
  def test_three_levels_of_dependence
    topic = Topic.create "title" => "neat and simple"
    reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
    silly_reply = reply.silly_replies.create "title" => "neat and simple", "content" => "ain't complaining"
    
    assert_nothing_raised { topic.destroy }
  end

571
  uses_transaction :test_dependence_with_transaction_support_on_failure
D
Initial  
David Heinemeier Hansson 已提交
572
  def test_dependence_with_transaction_support_on_failure
573
    firm = companies(:first_firm)
D
Initial  
David Heinemeier Hansson 已提交
574
    clients = firm.clients
575
    assert_equal 2, clients.length
D
Initial  
David Heinemeier Hansson 已提交
576 577 578 579
    clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }

    firm.destroy rescue "do nothing"

580
    assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
D
Initial  
David Heinemeier Hansson 已提交
581 582 583
  end

  def test_dependence_on_account
584
    assert_equal 2, Account.count
585
    companies(:first_firm).destroy
586
    assert_equal 1, Account.count
D
Initial  
David Heinemeier Hansson 已提交
587 588 589
  end

  def test_included_in_collection
590
    assert companies(:first_firm).clients.include?(Client.find(2))
D
Initial  
David Heinemeier Hansson 已提交
591 592 593
  end

  def test_adding_array_and_collection
594
    assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
D
Initial  
David Heinemeier Hansson 已提交
595
  end
596 597 598 599 600

  def test_find_all_without_conditions
    firm = companies(:first_firm)
    assert_equal 2, firm.clients.find(:all).length
  end
601 602

  def test_replace_with_less
603
    firm = Firm.find(:first)
604 605 606 607 608 609 610
    firm.clients = [companies(:first_client)]
    assert firm.save, "Could not save firm"
    firm.reload
    assert_equal 1, firm.clients.length
  end
  
  def test_replace_with_new
611
    firm = Firm.find(:first)
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    new_client = Client.new("name" => "New Client")
    firm.clients = [companies(:second_client),new_client]
    firm.save
    firm.reload
    assert_equal 2, firm.clients.length
    assert !firm.clients.include?(:first_client)
  end
  
  def test_replace_on_new_object
    firm = Firm.new("name" => "New Firm")
    firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
    assert firm.save
    firm.reload
    assert_equal 2, firm.clients.length
    assert firm.clients.include?(Client.find_by_name("New Client"))
  end
  
  def test_assign_ids
    firm = Firm.new("name" => "Apple")
    firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
    firm.save
    firm.reload
    assert_equal 2, firm.clients.length
    assert firm.clients.include?(companies(:second_client))
  end
D
Initial  
David Heinemeier Hansson 已提交
637 638 639
end

class BelongsToAssociationsTest < Test::Unit::TestCase
640 641
  fixtures :accounts, :companies, :developers, :projects, :topics,
           :developers_projects
D
David Heinemeier Hansson 已提交
642
  
D
Initial  
David Heinemeier Hansson 已提交
643 644
  def test_belongs_to
    Client.find(3).firm.name
645
    assert_equal companies(:first_firm).name, Client.find(3).firm.name
D
Initial  
David Heinemeier Hansson 已提交
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
    assert !Client.find(3).firm.nil?, "Microsoft should have a firm"   
  end

  def test_type_mismatch
    assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
    assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
  end

  def test_natural_assignment
    apple = Firm.create("name" => "Apple")
    citibank = Account.create("credit_limit" => 10)
    citibank.firm = apple
    assert_equal apple.id, citibank.firm_id
  end
  
661 662 663 664 665 666 667 668 669 670 671 672 673
  def test_creating_the_belonging_object
    citibank = Account.create("credit_limit" => 10)
    apple    = citibank.create_firm("name" => "Apple")
    assert_equal apple, citibank.firm
  end

  def test_building_the_belonging_object
    citibank = Account.create("credit_limit" => 10)
    apple    = citibank.build_firm("name" => "Apple")
    citibank.save
    assert_equal apple.id, citibank.firm_id
  end
  
D
Initial  
David Heinemeier Hansson 已提交
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
  def test_natural_assignment_to_nil
    client = Client.find(3)
    client.firm = nil
    client.save
    assert_nil client.firm(true)
    assert_nil client.client_of
  end
  
  def test_with_different_class_name
    assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
    assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
  end

  def test_with_condition
    assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
    assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
  end
  
  def test_belongs_to_counter
    debate = Topic.create("title" => "debate")
    assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"

    trash = debate.replies.create("title" => "blah!", "content" => "world around!")
    assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"

    trash.destroy
    assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
  end

703
  def test_assignment_before_parent_saved
704
    client = Client.find(:first)
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
    apple = Firm.new("name" => "Apple")
    client.firm = apple
    assert_equal apple, client.firm
    assert apple.new_record?
    assert client.save
    assert apple.save
    assert !apple.new_record?
    assert_equal apple, client.firm
    assert_equal apple, client.firm(true)
  end

  def test_assignment_before_child_saved
    final_cut = Client.new("name" => "Final Cut")
    firm = Firm.find(1)
    final_cut.firm = firm
    assert final_cut.new_record?
    assert final_cut.save
    assert !final_cut.new_record?
    assert !firm.new_record?
    assert_equal firm, final_cut.firm
    assert_equal firm, final_cut.firm(true)
  end

  def test_assignment_before_either_saved
    final_cut = Client.new("name" => "Final Cut")
    apple = Firm.new("name" => "Apple")
    final_cut.firm = apple
    assert final_cut.new_record?
    assert apple.new_record?
    assert final_cut.save
    assert !final_cut.new_record?
    assert !apple.new_record?
    assert_equal apple, final_cut.firm
    assert_equal apple, final_cut.firm(true)
  end

D
David Heinemeier Hansson 已提交
741 742
  def test_new_record_with_foreign_key_but_no_object
    c = Client.new("firm_id" => 1)
743
    assert_equal Firm.find(:first), c.firm_with_basic_id
D
David Heinemeier Hansson 已提交
744 745
  end

746 747 748 749 750
  def test_forgetting_the_load_when_foreign_key_enters_late
    c = Client.new
    assert_nil c.firm_with_basic_id

    c.firm_id = 1
751
    assert_equal Firm.find(:first), c.firm_with_basic_id
752 753
  end

754 755
  def test_field_name_same_as_foreign_key
    computer = Computer.find 1
756
    assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
757 758
  end

D
Initial  
David Heinemeier Hansson 已提交
759 760 761 762 763 764 765 766 767 768
  def xtest_counter_cache
    apple = Firm.create("name" => "Apple")
    final_cut = apple.clients.create("name" => "Final Cut")

    apple.clients.to_s
    assert_equal 1, apple.clients.size, "Created one client"
    
    apple.companies_count = 2
    apple.save

769
    apple = Firm.find(:first, :conditions => "name = 'Apple'")
D
Initial  
David Heinemeier Hansson 已提交
770 771 772 773 774
    assert_equal 2, apple.clients.size, "Should use the new cached number"

    apple.clients.to_s 
    assert_equal 1, apple.clients.size, "Should not use the cached number, but go to the database"
  end
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813

  def test_store_two_association_with_one_save
    num_orders = Order.count
    num_customers = Customer.count
    order = Order.new 

    customer1 = order.billing = Customer.new
    customer2 = order.shipping = Customer.new 
    assert order.save
    assert_equal customer1, order.billing
    assert_equal customer2, order.shipping

    order.reload

    assert_equal customer1, order.billing
    assert_equal customer2, order.shipping        

    assert_equal num_orders +1, Order.count
    assert_equal num_customers +2, Customer.count
  end
  
  def test_store_association_in_two_relations_with_one_save
    num_orders = Order.count
    num_customers = Customer.count
    order = Order.new 
    
    customer = order.billing = order.shipping = Customer.new 
    assert order.save
    assert_equal customer, order.billing
    assert_equal customer, order.shipping
    
    order.reload
    
    assert_equal customer, order.billing
    assert_equal customer, order.shipping        
    
    assert_equal num_orders +1, Order.count
    assert_equal num_customers +1, Customer.count
  end
J
Jamis Buck 已提交
814 815 816 817 818 819 820 821 822

  def test_association_assignment_sticks
    client = Client.find(:first)
    apple = Firm.create("name" => "Apple")
    client.firm = apple
    client.save!
    client.reload
    assert_equal apple.id, client.firm_id
  end
823
  
D
Initial  
David Heinemeier Hansson 已提交
824 825 826
end


827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
class ProjectWithAfterCreateHook < ActiveRecord::Base
  set_table_name 'projects'
  has_and_belongs_to_many :developers,
    :class_name => "DeveloperForProjectWithAfterCreateHook",
    :join_table => "developers_projects",
    :foreign_key => "project_id",
    :association_foreign_key => "developer_id"

  after_create :add_david

  def add_david
    david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
    david.projects << self
  end
end

class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
  set_table_name 'developers'
  has_and_belongs_to_many :projects,
    :class_name => "ProjectWithAfterCreateHook",
    :join_table => "developers_projects",
    :association_foreign_key => "project_id",
    :foreign_key => "developer_id"
end


D
Initial  
David Heinemeier Hansson 已提交
853
class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
854
  fixtures :accounts, :companies, :developers, :projects, :developers_projects
D
Initial  
David Heinemeier Hansson 已提交
855 856 857 858 859 860 861 862 863 864
  
  def test_has_and_belongs_to_many
    david = Developer.find(1)

    assert !david.projects.empty?
    assert_equal 2, david.projects.size

    active_record = Project.find(1)
    assert !active_record.developers.empty?
    assert_equal 2, active_record.developers.size
865
    assert active_record.developers.include?(david)
D
Initial  
David Heinemeier Hansson 已提交
866
  end
867

D
Initial  
David Heinemeier Hansson 已提交
868 869
  def test_adding_single
    jamis = Developer.find(2)
870
    jamis.projects.reload # causing the collection to load 
D
Initial  
David Heinemeier Hansson 已提交
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
    action_controller = Project.find(2)
    assert_equal 1, jamis.projects.size
    assert_equal 1, action_controller.developers.size    
    
    jamis.projects << action_controller

    assert_equal 2, jamis.projects.size
    assert_equal 2, jamis.projects(true).size
    assert_equal 2, action_controller.developers(true).size
  end

  def test_adding_type_mismatch
    jamis = Developer.find(2)
    assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
    assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
  end

  def test_adding_from_the_project
    jamis = Developer.find(2)
    action_controller = Project.find(2)
891
    action_controller.developers.reload
D
Initial  
David Heinemeier Hansson 已提交
892 893 894 895 896 897 898 899 900 901
    assert_equal 1, jamis.projects.size
    assert_equal 1, action_controller.developers.size

    action_controller.developers << jamis 
    
    assert_equal 2, jamis.projects(true).size
    assert_equal 2, action_controller.developers.size
    assert_equal 2, action_controller.developers(true).size
  end

902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
  def test_adding_from_the_project_fixed_timestamp
    jamis = Developer.find(2)
    action_controller = Project.find(2)
    action_controller.developers.reload
    assert_equal 1, jamis.projects.size
    assert_equal 1, action_controller.developers.size
    updated_at = jamis.updated_at

    action_controller.developers << jamis

    assert_equal updated_at, jamis.updated_at
    assert_equal 2, jamis.projects(true).size
    assert_equal 2, action_controller.developers.size
    assert_equal 2, action_controller.developers(true).size
  end

D
Initial  
David Heinemeier Hansson 已提交
918
  def test_adding_multiple
919
    aredridel = Developer.new("name" => "Aredridel")
920 921 922 923 924
    aredridel.save
    aredridel.projects.reload
    aredridel.projects.push(Project.find(1), Project.find(2))
    assert_equal 2, aredridel.projects.size
    assert_equal 2, aredridel.projects(true).size
D
Initial  
David Heinemeier Hansson 已提交
925 926 927
  end

  def test_adding_a_collection
928
    aredridel = Developer.new("name" => "Aredridel")
929 930 931 932 933
    aredridel.save
    aredridel.projects.reload
    aredridel.projects.concat([Project.find(1), Project.find(2)])
    assert_equal 2, aredridel.projects.size
    assert_equal 2, aredridel.projects(true).size
D
Initial  
David Heinemeier Hansson 已提交
934
  end
935

936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
  def test_adding_uses_default_values_on_join_table
    ac = projects(:action_controller)
    assert !developers(:jamis).projects.include?(ac)
    developers(:jamis).projects << ac

    assert developers(:jamis, :reload).projects.include?(ac)
    project = developers(:jamis).projects.detect { |p| p == ac }
    assert_equal 1, project.access_level.to_i
  end

  def test_adding_uses_explicit_values_on_join_table
    ac = projects(:action_controller)
    assert !developers(:jamis).projects.include?(ac)
    developers(:jamis).projects.push_with_attributes(ac, :access_level => 3)

    assert developers(:jamis, :reload).projects.include?(ac)
    project = developers(:jamis).projects.detect { |p| p == ac }
    assert_equal 3, project.access_level.to_i
  end

956 957 958
  def test_habtm_adding_before_save
    no_of_devels = Developer.count
    no_of_projects = Project.count
959
    aredridel = Developer.new("name" => "Aredridel")
960 961
    aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
    assert aredridel.new_record?
962
    assert p.new_record?
963 964
    assert aredridel.save
    assert !aredridel.new_record?
965 966
    assert_equal no_of_devels+1, Developer.count
    assert_equal no_of_projects+1, Project.count
967 968
    assert_equal 2, aredridel.projects.size
    assert_equal 2, aredridel.projects(true).size
969 970
  end

971 972 973 974
  def test_habtm_adding_before_save_with_join_attributes
    no_of_devels = Developer.count
    no_of_projects = Project.count
    now = Date.today
975
    sqlnow = Time.now.strftime("%Y/%m/%d 00:00:00")
976 977 978 979 980 981 982 983 984 985 986 987 988 989
    ken = Developer.new("name" => "Ken")
    ken.projects.push_with_attributes( Project.find(1), :joined_on => now )
    p = Project.new("name" => "Foomatic")
    ken.projects.push_with_attributes( p, :joined_on => now )
    assert ken.new_record?
    assert p.new_record?
    assert ken.save
    assert !ken.new_record?
    assert_equal no_of_devels+1, Developer.count
    assert_equal no_of_projects+1, Project.count
    assert_equal 2, ken.projects.size
    assert_equal 2, ken.projects(true).size

    kenReloaded = Developer.find_by_name 'Ken'
990 991 992 993 994 995 996
    # SQL Server doesn't have a separate column type just for dates, 
    # so the time is in the string and incorrectly formatted
    if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
      kenReloaded.projects.each { |prj| assert_equal(sqlnow, prj.joined_on.to_s) }
    else
      kenReloaded.projects.each { |prj| assert_equal(now.to_s, prj.joined_on.to_s) }
    end
997 998
  end

999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
  def test_build
    devel = Developer.find(1)
    proj = devel.projects.build("name" => "Projekt")
    assert_equal devel.projects.last, proj
    assert proj.new_record?
    devel.save
    assert !proj.new_record?
    assert_equal devel.projects.last, proj
  end
  
  def test_create
    devel = Developer.find(1)
    proj = devel.projects.create("name" => "Projekt")
    assert_equal devel.projects.last, proj
    assert !proj.new_record?
  end
D
Initial  
David Heinemeier Hansson 已提交
1015 1016
  
  def test_uniq_after_the_fact
1017 1018 1019 1020
    developers(:jamis).projects << projects(:active_record)
    developers(:jamis).projects << projects(:active_record)
    assert_equal 3, developers(:jamis).projects.size
    assert_equal 1, developers(:jamis).projects.uniq.size
D
Initial  
David Heinemeier Hansson 已提交
1021 1022 1023
  end

  def test_uniq_before_the_fact
1024 1025
    projects(:active_record).developers << developers(:jamis)
    projects(:active_record).developers << developers(:david)
1026
    assert_equal 2, projects(:active_record, :reload).developers.size
D
Initial  
David Heinemeier Hansson 已提交
1027 1028 1029 1030 1031
  end
  
  def test_deleting
    david = Developer.find(1)
    active_record = Project.find(1)
1032
    david.projects.reload
D
Initial  
David Heinemeier Hansson 已提交
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
    assert_equal 2, david.projects.size
    assert_equal 2, active_record.developers.size

    david.projects.delete(active_record)
    
    assert_equal 1, david.projects.size
    assert_equal 1, david.projects(true).size
    assert_equal 1, active_record.developers(true).size
  end

  def test_deleting_array
    david = Developer.find(1)
1045
    david.projects.reload
1046
    david.projects.delete(Project.find(:all))
D
Initial  
David Heinemeier Hansson 已提交
1047 1048 1049 1050
    assert_equal 0, david.projects.size
    assert_equal 0, david.projects(true).size
  end

1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
  def test_deleting_with_sql
    david = Developer.find(1)
    active_record = Project.find(1)
    active_record.developers.reload
    assert_equal 2, active_record.developers_by_sql.size
    
    active_record.developers_by_sql.delete(david)
    assert_equal 1, active_record.developers_by_sql(true).size
  end

  def test_deleting_array_with_sql
    active_record = Project.find(1)
    active_record.developers.reload
    assert_equal 2, active_record.developers_by_sql.size
    
1066
    active_record.developers_by_sql.delete(Developer.find(:all))
1067 1068 1069
    assert_equal 0, active_record.developers_by_sql(true).size
  end

D
Initial  
David Heinemeier Hansson 已提交
1070 1071
  def test_deleting_all
    david = Developer.find(1)
1072
    david.projects.reload
D
Initial  
David Heinemeier Hansson 已提交
1073 1074 1075 1076 1077 1078 1079
    david.projects.clear
    assert_equal 0, david.projects.size
    assert_equal 0, david.projects(true).size
  end

  def test_removing_associations_on_destroy
    Developer.find(1).destroy
1080
    assert Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
D
Initial  
David Heinemeier Hansson 已提交
1081 1082 1083
  end
  
  def test_additional_columns_from_join_table
1084 1085 1086 1087 1088 1089 1090
    # SQL Server doesn't have a separate column type just for dates, 
    # so the time is in the string and incorrectly formatted
    if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
      assert_equal Time.mktime(2004, 10, 10).strftime("%Y/%m/%d 00:00:00"), Developer.find(1).projects.first.joined_on.to_s
    else
      assert_equal Date.new(2004, 10, 10).to_s, Developer.find(1).projects.first.joined_on.to_s
    end
D
Initial  
David Heinemeier Hansson 已提交
1091 1092 1093 1094
  end
  
  def test_destroy_all
    david = Developer.find(1)
1095
    david.projects.reload
D
Initial  
David Heinemeier Hansson 已提交
1096 1097 1098 1099 1100 1101 1102
    assert !david.projects.empty?
    david.projects.destroy_all
    assert david.projects.empty?
    assert david.projects(true).empty?
  end

  def test_rich_association
1103 1104
    jamis = developers(:jamis)
    jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
1105 1106 1107 1108 1109 1110 1111 1112 1113
    # SQL Server doesn't have a separate column type just for dates, 
    # so the time is in the string and incorrectly formatted
    if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
      assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
      assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
    else
      assert_equal Date.today.to_s, jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
      assert_equal Date.today.to_s, developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
    end
D
Initial  
David Heinemeier Hansson 已提交
1114 1115 1116
  end

  def test_associations_with_conditions
1117 1118
    assert_equal 2, projects(:active_record).developers.size
    assert_equal 1, projects(:active_record).developers_named_david.size
1119 1120 1121 1122

    assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
    assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)

1123
    projects(:active_record).developers_named_david.clear
1124
    assert_equal 1, projects(:active_record, :reload).developers.size
D
Initial  
David Heinemeier Hansson 已提交
1125 1126 1127 1128
  end
  
  def test_find_in_association
    # Using sql
1129
    assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
D
Initial  
David Heinemeier Hansson 已提交
1130 1131
    
    # Using ruby
1132 1133 1134
    active_record = projects(:active_record)
    active_record.developers.reload
    assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
D
Initial  
David Heinemeier Hansson 已提交
1135
  end
1136

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
  def test_new_with_values_in_collection
    jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
    david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
    project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
    project.developers << jamis
    project.save!
    project.reload

    assert project.developers.include?(jamis)
    assert project.developers.include?(david)
  end

1149
  def xtest_find_in_association_with_options
1150
    developers = projects(:active_record).developers.find(:all)
1151 1152
    assert_equal 2, developers.size
    
1153 1154
    assert_equal developers(:david), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
    assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
1155
  end
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
  
  def test_replace_with_less
    david = developers(:david)
    david.projects = [projects(:action_controller)]
    assert david.save
    assert_equal 1, david.projects.length
  end

  def test_replace_with_new
    david = developers(:david)
    david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
    david.save
    assert_equal 2, david.projects.length
    assert !david.projects.include?(projects(:active_record))
  end
  
  def test_replace_on_new_object
    new_developer = Developer.new("name" => "Matz")
    new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
    new_developer.save
    assert_equal 2, new_developer.projects.length
  end
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191

  def test_consider_type
    developer = Developer.find(:first)
    special_project = SpecialProject.create("name" => "Special Project")
  
    other_project = developer.projects.first
    developer.special_projects << special_project
    developer.reload
  
    assert developer.projects.include?(special_project)
    assert developer.special_projects.include?(special_project)
    assert !developer.special_projects.include?(other_project)
  end

1192
end