join_model_test.rb 23.4 KB
Newer Older
1
require 'abstract_unit'
J
Jeremy Kemper 已提交
2 3 4 5 6 7 8 9 10 11 12 13
require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/item'
require 'models/comment'
require 'models/author'
require 'models/category'
require 'models/categorization'
require 'models/vertex'
require 'models/edge'
require 'models/book'
require 'models/citation'
14

15
class AssociationsJoinModelTest < ActiveSupport::TestCase
16
  self.use_transactional_fixtures = false
17
  fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books
18 19

  def test_has_many
20
    assert authors(:david).categories.include?(categories(:general))
21
  end
22

23
  def test_has_many_inherited
24
    assert authors(:mary).categories.include?(categories(:sti_test))
25
  end
26

27
  def test_inherited_has_many
28 29 30 31 32 33
    assert categories(:sti_test).authors.include?(authors(:mary))
  end

  def test_has_many_uniq_through_join_model
    assert_equal 2, authors(:mary).categorized_posts.size
    assert_equal 1, authors(:mary).unique_categorized_posts.size
34
  end
J
Jeremy Kemper 已提交
35

36 37 38 39 40 41 42 43
  def test_has_many_uniq_through_count
    author = authors(:mary)
    assert !authors(:mary).unique_categorized_posts.loaded?
    assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count }
    assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title) }
    assert_queries(1) { assert_equal 0, author.unique_categorized_posts.count(:title, :conditions => "title is NULL") }
    assert !authors(:mary).unique_categorized_posts.loaded?
  end
J
Jeremy Kemper 已提交
44

45
  def test_polymorphic_has_many
46
    assert posts(:welcome).taggings.include?(taggings(:welcome_general))
47
  end
48

49 50 51
  def test_polymorphic_has_one
    assert_equal taggings(:welcome_general), posts(:welcome).tagging
  end
52

53
  def test_polymorphic_belongs_to
54 55
    assert_equal posts(:welcome), posts(:welcome).taggings.first.taggable
  end
56 57

  def test_polymorphic_has_many_going_through_join_model
58 59 60 61
    assert_equal tags(:general), tag = posts(:welcome).tags.first
    assert_no_queries do
      tag.tagging
    end
62
  end
63

R
Rick Olson 已提交
64 65 66 67 68
  def test_count_polymorphic_has_many
    assert_equal 1, posts(:welcome).taggings.count
    assert_equal 1, posts(:welcome).tags.count
  end

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
  def test_polymorphic_has_many_going_through_join_model_with_find
    assert_equal tags(:general), tag = posts(:welcome).tags.find(:first)
    assert_no_queries do
      tag.tagging
    end
  end

  def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection
    assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
    assert_no_queries do
      tag.tagging
    end
  end

  def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection_with_find
    assert_equal tags(:general), tag = posts(:welcome).funky_tags.find(:first)
    assert_no_queries do
      tag.tagging
    end
  end

90 91 92 93 94 95 96 97 98 99 100
  def test_polymorphic_has_many_going_through_join_model_with_disabled_include
    assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
    assert_queries 1 do
      tag.tagging
    end
  end

  def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
    assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
    tag.author_id
  end
101

102 103 104 105 106
  def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
    assert_equal tags(:misc), taggings(:welcome_general).super_tag
    assert_equal tags(:misc), posts(:welcome).super_tags.first
  end

107 108 109
  def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
    post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
    assert_instance_of SubStiPost, post
J
Jeremy Kemper 已提交
110

111 112 113 114
    tagging = tags(:misc).taggings.create(:taggable => post)
    assert_equal "SubStiPost", tagging.taggable_type
  end

115 116 117
  def test_polymorphic_has_many_going_through_join_model_with_inheritance
    assert_equal tags(:general), posts(:thinking).tags.first
  end
118 119 120 121 122

  def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
    assert_equal tags(:general), posts(:thinking).funky_tags.first
  end

123 124 125
  def test_polymorphic_has_many_create_model_with_inheritance
    post = posts(:thinking)
    assert_instance_of SpecialPost, post
J
Jeremy Kemper 已提交
126

127 128 129
    tagging = tags(:misc).taggings.create(:taggable => post)
    assert_equal "Post", tagging.taggable_type
  end
130 131 132 133 134 135

  def test_polymorphic_has_one_create_model_with_inheritance
    tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
    assert_equal "Post", tagging.taggable_type
  end

136 137 138 139 140 141 142 143 144 145 146 147 148
  def test_set_polymorphic_has_many
    tagging = tags(:misc).taggings.create
    posts(:thinking).taggings << tagging
    assert_equal "Post", tagging.taggable_type
  end

  def test_set_polymorphic_has_one
    tagging = tags(:misc).taggings.create
    posts(:thinking).tagging = tagging
    assert_equal "Post", tagging.taggable_type
  end

  def test_create_polymorphic_has_many_with_scope
149 150
    old_count = posts(:welcome).taggings.count
    tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
151
    assert_equal "Post", tagging.taggable_type
152
    assert_equal old_count+1, posts(:welcome).taggings.count
153
  end
J
Jeremy Kemper 已提交
154

155 156 157 158 159 160
  def test_create_bang_polymorphic_with_has_many_scope
    old_count = posts(:welcome).taggings.count
    tagging = posts(:welcome).taggings.create!(:tag => tags(:misc))
    assert_equal "Post", tagging.taggable_type
    assert_equal old_count+1, posts(:welcome).taggings.count
  end
161 162

  def test_create_polymorphic_has_one_with_scope
163 164
    old_count = Tagging.count
    tagging = posts(:welcome).tagging.create(:tag => tags(:misc))
165
    assert_equal "Post", tagging.taggable_type
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
    assert_equal old_count+1, Tagging.count
  end

  def test_delete_polymorphic_has_many_with_delete_all
    assert_equal 1, posts(:welcome).taggings.count
    posts(:welcome).taggings.first.update_attribute :taggable_type, 'PostWithHasManyDeleteAll'
    post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)

    old_count = Tagging.count
    post.destroy
    assert_equal old_count-1, Tagging.count
    assert_equal 0, posts(:welcome).taggings.count
  end

  def test_delete_polymorphic_has_many_with_destroy
    assert_equal 1, posts(:welcome).taggings.count
    posts(:welcome).taggings.first.update_attribute :taggable_type, 'PostWithHasManyDestroy'
    post = find_post_with_dependency(1, :has_many, :taggings, :destroy)

    old_count = Tagging.count
    post.destroy
    assert_equal old_count-1, Tagging.count
    assert_equal 0, posts(:welcome).taggings.count
  end

  def test_delete_polymorphic_has_many_with_nullify
    assert_equal 1, posts(:welcome).taggings.count
    posts(:welcome).taggings.first.update_attribute :taggable_type, 'PostWithHasManyNullify'
    post = find_post_with_dependency(1, :has_many, :taggings, :nullify)

    old_count = Tagging.count
    post.destroy
    assert_equal old_count, Tagging.count
    assert_equal 0, posts(:welcome).taggings.count
  end

  def test_delete_polymorphic_has_one_with_destroy
    assert posts(:welcome).tagging
    posts(:welcome).tagging.update_attribute :taggable_type, 'PostWithHasOneDestroy'
    post = find_post_with_dependency(1, :has_one, :tagging, :destroy)

    old_count = Tagging.count
    post.destroy
    assert_equal old_count-1, Tagging.count
    assert_nil posts(:welcome).tagging(true)
  end

  def test_delete_polymorphic_has_one_with_nullify
    assert posts(:welcome).tagging
    posts(:welcome).tagging.update_attribute :taggable_type, 'PostWithHasOneNullify'
    post = find_post_with_dependency(1, :has_one, :tagging, :nullify)

    old_count = Tagging.count
    post.destroy
    assert_equal old_count, Tagging.count
    assert_nil posts(:welcome).tagging(true)
222 223
  end

224
  def test_has_many_with_piggyback
225
    assert_equal "2", categories(:sti_test).authors.first.post_id.to_s
226
  end
227 228 229 230 231 232 233 234 235 236

  def test_include_has_many_through
    posts              = Post.find(:all, :order => 'posts.id')
    posts_with_authors = Post.find(:all, :include => :authors, :order => 'posts.id')
    assert_equal posts.length, posts_with_authors.length
    posts.length.times do |i|
      assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
    end
  end

237 238 239 240 241 242 243
  def test_include_polymorphic_has_one
    post    = Post.find_by_id(posts(:welcome).id, :include => :tagging)
    tagging = taggings(:welcome_general)
    assert_no_queries do
      assert_equal tagging, post.tagging
    end
  end
J
Jeremy Kemper 已提交
244

245 246 247 248 249 250 251
  def test_include_polymorphic_has_one_defined_in_abstract_parent
    item    = Item.find_by_id(items(:dvd).id, :include => :tagging)
    tagging = taggings(:godfather)
    assert_no_queries do
      assert_equal tagging, item.tagging
    end
  end
J
Jeremy Kemper 已提交
252

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
  def test_include_polymorphic_has_many_through
    posts           = Post.find(:all, :order => 'posts.id')
    posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
    assert_equal posts.length, posts_with_tags.length
    posts.length.times do |i|
      assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
    end
  end

  def test_include_polymorphic_has_many
    posts               = Post.find(:all, :order => 'posts.id')
    posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
    assert_equal posts.length, posts_with_taggings.length
    posts.length.times do |i|
      assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
    end
  end

271 272 273
  def test_has_many_find_all
    assert_equal [categories(:general)], authors(:david).categories.find(:all)
  end
J
Jeremy Kemper 已提交
274

275 276 277
  def test_has_many_find_first
    assert_equal categories(:general), authors(:david).categories.find(:first)
  end
278 279 280 281

  def test_has_many_with_hash_conditions
    assert_equal categories(:general), authors(:david).categories_like_general.find(:first)
  end
J
Jeremy Kemper 已提交
282

283 284 285 286
  def test_has_many_find_conditions
    assert_equal categories(:general), authors(:david).categories.find(:first, :conditions => "categories.name = 'General'")
    assert_equal nil, authors(:david).categories.find(:first, :conditions => "categories.name = 'Technology'")
  end
287

288
  def test_has_many_class_methods_called_by_method_missing
289
    assert_equal categories(:general), authors(:david).categories.find_all_by_name('General').first
290
    assert_equal nil, authors(:david).categories.find_by_name('Technology')
291
  end
292 293 294 295 296

  def test_has_many_going_through_join_model_with_custom_foreign_key
    assert_equal [], posts(:thinking).authors
    assert_equal [authors(:mary)], posts(:authorless).authors
  end
297 298 299 300 301 302 303 304

  def test_belongs_to_polymorphic_with_counter_cache
    assert_equal 0, posts(:welcome)[:taggings_count]
    tagging = posts(:welcome).taggings.create(:tag => tags(:general))
    assert_equal 1, posts(:welcome, :reload)[:taggings_count]
    tagging.destroy
    assert posts(:welcome, :reload)[:taggings_count].zero?
  end
305

306
  def test_unavailable_through_reflection
307
    assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
308 309
  end

310 311 312 313 314
  def test_has_many_through_join_model_with_conditions
    assert_equal [], posts(:welcome).invalid_taggings
    assert_equal [], posts(:welcome).invalid_tags
  end

315
  def test_has_many_polymorphic
316
    assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicError do
317
      assert_equal posts(:welcome, :thinking), tags(:general).taggables
318
    end
319
    assert_raise ActiveRecord::EagerLoadPolymorphicError do
320
      assert_equal posts(:welcome, :thinking), tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
321 322
    end
  end
J
Jeremy Kemper 已提交
323

324
  def test_has_many_polymorphic_with_source_type
325
    assert_equal posts(:welcome, :thinking), tags(:general).tagged_posts
326 327 328 329
  end

  def test_eager_has_many_polymorphic_with_source_type
    tag_with_include = Tag.find(tags(:general).id, :include => :tagged_posts)
330
    desired = posts(:welcome, :thinking)
331 332 333
    assert_no_queries do
      assert_equal desired, tag_with_include.tagged_posts
    end
334
    assert_equal 4, tag_with_include.taggings.length
335
  end
336

337
  def test_has_many_through_has_many_find_all
338
    assert_equal comments(:greetings), authors(:david).comments.find(:all, :order => 'comments.id').first
339 340
  end

341 342 343 344
  def test_has_many_through_has_many_find_all_with_custom_class
    assert_equal comments(:greetings), authors(:david).funky_comments.find(:all, :order => 'comments.id').first
  end

345
  def test_has_many_through_has_many_find_first
346
    assert_equal comments(:greetings), authors(:david).comments.find(:first, :order => 'comments.id')
347 348 349
  end

  def test_has_many_through_has_many_find_conditions
350 351
    options = { :conditions => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
    assert_equal comments(:does_it_hurt), authors(:david).comments.find(:first, options)
352 353 354 355 356 357
  end

  def test_has_many_through_has_many_find_by_id
    assert_equal comments(:more_greetings), authors(:david).comments.find(2)
  end

358 359 360 361 362
  def test_has_many_through_polymorphic_has_one
    assert_raise(ActiveRecord::HasManyThroughSourceAssociationMacroError) { authors(:david).tagging }
  end

  def test_has_many_through_polymorphic_has_many
363
    assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.uniq.sort_by { |t| t.id }
364 365
  end

366
  def test_include_has_many_through_polymorphic_has_many
367
    author            = Author.find_by_id(authors(:david).id, :include => :taggings)
368
    expected_taggings = taggings(:welcome_general, :thinking_general)
369 370 371 372 373
    assert_no_queries do
      assert_equal expected_taggings, author.taggings.uniq.sort_by { |t| t.id }
    end
  end

374 375 376 377 378 379 380 381
  def test_has_many_through_has_many_through
    assert_raise(ActiveRecord::HasManyThroughSourceAssociationMacroError) { authors(:david).tags }
  end

  def test_has_many_through_habtm
    assert_raise(ActiveRecord::HasManyThroughSourceAssociationMacroError) { authors(:david).post_categories }
  end

382 383 384 385 386 387 388
  def test_eager_load_has_many_through_has_many
    author = Author.find :first, :conditions => ['name = ?', 'David'], :include => :comments, :order => 'comments.id'
    SpecialComment.new; VerySpecialComment.new
    assert_no_queries do
      assert_equal [1,2,3,5,6,7,8,9,10], author.comments.collect(&:id)
    end
  end
J
Jeremy Kemper 已提交
389

390 391 392 393 394 395
  def test_eager_load_has_many_through_has_many_with_conditions
    post = Post.find(:first, :include => :invalid_tags)
    assert_no_queries do
      post.invalid_tags
    end
  end
396

397 398 399 400 401 402 403
  def test_eager_belongs_to_and_has_one_not_singularized
    assert_nothing_raised do
      Author.find(:first, :include => :author_address)
      AuthorAddress.find(:first, :include => :author)
    end
  end

404 405 406 407 408 409 410 411
  def test_self_referential_has_many_through
    assert_equal [authors(:mary)], authors(:david).favorite_authors
    assert_equal [],               authors(:mary).favorite_authors
  end

  def test_add_to_self_referential_has_many_through
    new_author = Author.create(:name => "Bob")
    authors(:david).author_favorites.create :favorite_author => new_author
R
Rick Olson 已提交
412
    assert_equal new_author, authors(:david).reload.favorite_authors.first
413
  end
J
Jeremy Kemper 已提交
414

415 416 417 418 419
  def test_has_many_through_uses_conditions_specified_on_the_has_many_association
    author = Author.find(:first)
    assert !author.comments.blank?
    assert author.nonexistant_comments.blank?
  end
420

421 422 423 424
  def test_has_many_through_uses_correct_attributes
    assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
  end

425 426 427 428
  def test_raise_error_when_adding_new_record_to_has_many_through
    assert_raise(ActiveRecord::HasManyThroughCantAssociateNewRecords) { posts(:thinking).tags << tags(:general).clone }
    assert_raise(ActiveRecord::HasManyThroughCantAssociateNewRecords) { posts(:thinking).clone.tags << tags(:general) }
    assert_raise(ActiveRecord::HasManyThroughCantAssociateNewRecords) { posts(:thinking).tags.build }
429
    assert_raise(ActiveRecord::HasManyThroughCantAssociateNewRecords) { posts(:thinking).tags.new }
430
  end
431 432

  def test_create_associate_when_adding_to_has_many_through
433 434
    count = posts(:thinking).tags.count
    push = Tag.create!(:name => 'pushme')
435 436 437 438 439 440 441 442 443
    post_thinking = posts(:thinking)
    assert_nothing_raised { post_thinking.tags << push }
    assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
                message = "Expected a Tag in tags collection, got #{wrong.class}.")
    assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
                message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
    assert_equal(count + 1, post_thinking.tags.size)
    assert_equal(count + 1, post_thinking.tags(true).size)

444
    assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
445 446 447 448 449 450 451 452 453 454 455 456 457 458
    assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
                message = "Expected a Tag in tags collection, got #{wrong.class}.")
    assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
                message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
    assert_equal(count + 2, post_thinking.tags.size)
    assert_equal(count + 2, post_thinking.tags(true).size)

    assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
    assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
                message = "Expected a Tag in tags collection, got #{wrong.class}.")
    assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
                message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
    assert_equal(count + 4, post_thinking.tags.size)
    assert_equal(count + 4, post_thinking.tags(true).size)
459 460 461

    # Raises if the wrong reflection name is used to set the Edge belongs_to
    assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
462 463
  end

464 465 466 467 468 469
  def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
    author = authors(:david)
    assert_equal 9, author.comments.size
    assert !author.comments.loaded?
  end

470 471 472 473 474 475 476 477 478
  uses_mocha('has_many_through_collection_size_uses_counter_cache_if_it_exists') do
    def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
      author = authors(:david)
      author.stubs(:read_attribute).with('comments_count').returns(100)
      assert_equal 100, author.comments.size
      assert !author.comments.loaded?
    end
  end

479 480 481 482 483 484 485 486 487
  def test_adding_junk_to_has_many_through_should_raise_type_mismatch
    assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
  end

  def test_adding_to_has_many_through_should_return_self
    tags = posts(:thinking).tags
    assert_equal tags, posts(:thinking).tags.push(tags(:general))
  end

488 489 490 491 492 493 494 495 496 497 498 499 500 501
  def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
    count = books(:awdr).references.count
    references_before = books(:awdr).references
    book = Book.create!(:name => 'Getting Real')
    book_awdr = books(:awdr)
    book_awdr.references << book
    assert_equal(count + 1, book_awdr.references(true).size)

    assert_nothing_raised { book_awdr.references.delete(book) }
    assert_equal(count, book_awdr.references.size)
    assert_equal(count, book_awdr.references(true).size)
    assert_equal(references_before.sort, book_awdr.references.sort)
  end

502 503 504 505 506 507 508 509
  def test_delete_associate_when_deleting_from_has_many_through
    count = posts(:thinking).tags.count
    tags_before = posts(:thinking).tags
    tag = Tag.create!(:name => 'doomed')
    post_thinking = posts(:thinking)
    post_thinking.tags << tag
    assert_equal(count + 1, post_thinking.tags(true).size)

J
Jeremy Kemper 已提交
510
    assert_nothing_raised { post_thinking.tags.delete(tag) }
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
    assert_equal(count, post_thinking.tags.size)
    assert_equal(count, post_thinking.tags(true).size)
    assert_equal(tags_before.sort, post_thinking.tags.sort)
  end

  def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
    count = posts(:thinking).tags.count
    tags_before = posts(:thinking).tags
    doomed = Tag.create!(:name => 'doomed')
    doomed2 = Tag.create!(:name => 'doomed2')
    quaked = Tag.create!(:name => 'quaked')
    post_thinking = posts(:thinking)
    post_thinking.tags << doomed << doomed2
    assert_equal(count + 2, post_thinking.tags(true).size)

J
Jeremy Kemper 已提交
526
    assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
527 528 529 530 531 532 533 534
    assert_equal(count, post_thinking.tags.size)
    assert_equal(count, post_thinking.tags(true).size)
    assert_equal(tags_before.sort, post_thinking.tags.sort)
  end

  def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
    assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete("Uhh what now?") }
  end
535

536 537 538
  def test_has_many_through_sum_uses_calculations
    assert_nothing_raised { authors(:david).comments.sum(:post_id) }
  end
539

540 541 542
  def test_has_many_through_has_many_with_sti
    assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
  end
J
Jeremy Kemper 已提交
543

544 545 546 547 548
  def test_uniq_has_many_through_should_retain_order
    comment_ids = authors(:david).comments.map(&:id)
    assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
    assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
  end
549

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
  def test_polymorphic_has_many
    expected = taggings(:welcome_general)
    p = Post.find(posts(:welcome).id, :include => :taggings)
    assert_no_queries {assert p.taggings.include?(expected)}
    assert posts(:welcome).taggings.include?(taggings(:welcome_general))
  end

  def test_polymorphic_has_one
    expected = posts(:welcome)

    tagging  = Tagging.find(taggings(:welcome_general).id, :include => :taggable)
    assert_no_queries { assert_equal expected, tagging.taggable}
  end

  def test_polymorphic_belongs_to
    p = Post.find(posts(:welcome).id, :include => {:taggings => :taggable})
    assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
  end

  def test_preload_polymorphic_has_many_through
    posts           = Post.find(:all, :order => 'posts.id')
    posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
    assert_equal posts.length, posts_with_tags.length
    posts.length.times do |i|
      assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
    end
  end

  def test_preload_polymorph_many_types
    taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel']
    assert_no_queries do
      taggings.first.taggable.id
      taggings[1].taggable.id
    end

    taggables = taggings.map(&:taggable)
    assert taggables.include?(items(:dvd))
    assert taggables.include?(posts(:welcome))
  end

  def test_preload_polymorphic_has_many
    posts               = Post.find(:all, :order => 'posts.id')
    posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
    assert_equal posts.length, posts_with_taggings.length
    posts.length.times do |i|
      assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
    end
  end

  def test_belongs_to_shared_parent
    comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 1')
    assert_no_queries do
      assert_equal comments.first.post, comments[1].post
    end
  end

606 607 608 609 610 611 612 613 614 615
  private
    # create dynamic Post models to allow different dependency options
    def find_post_with_dependency(post_id, association, association_name, dependency)
      class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
      Post.find(post_id).update_attribute :type, class_name
      klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
      klass.set_table_name 'posts'
      klass.send(association, association_name, :as => :taggable, :dependent => dependency)
      klass.find(post_id)
    end
616
end