has_one_through_associations_test.rb 8.2 KB
Newer Older
1 2
require "cases/helper"
require 'models/club'
3
require 'models/member_type'
4 5 6
require 'models/member'
require 'models/membership'
require 'models/sponsor'
7 8
require 'models/organization'
require 'models/member_detail'
9 10 11
require 'models/minivan'
require 'models/dashboard'
require 'models/speedometer'
12 13 14
require 'models/author'
require 'models/post'
require 'models/comment'
15 16

class HasOneThroughAssociationsTest < ActiveRecord::TestCase
17 18
  fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans,
           :dashboards, :speedometers, :authors, :posts, :comments
19

20 21 22 23 24 25 26 27 28 29 30
  def setup
    @member = members(:groucho)
  end

  def test_has_one_through_with_has_one
    assert_equal clubs(:boring_club), @member.club
  end

  def test_has_one_through_with_has_many
    assert_equal clubs(:moustache_club), @member.favourite_club
  end
31

32 33 34 35 36 37
  def test_creating_association_creates_through_record
    new_member = Member.create(:name => "Chris")
    new_member.club = Club.create(:name => "LRUG")
    assert_not_nil new_member.current_membership
    assert_not_nil new_member.club
  end
38 39 40 41 42 43 44 45 46 47

  def test_creating_association_builds_through_record_for_new
    new_member = Member.new(:name => "Jane")
    new_member.club = clubs(:moustache_club)
    assert new_member.current_membership
    assert_equal clubs(:moustache_club), new_member.current_membership.club
    assert_equal clubs(:moustache_club), new_member.club
    assert new_member.save
    assert_equal clubs(:moustache_club), new_member.club
  end
48

49 50 51 52 53 54
  def test_replace_target_record
    new_club = Club.create(:name => "Marx Bros")
    @member.club = new_club
    @member.reload
    assert_equal new_club, @member.club
  end
55

56 57 58 59
  def test_replacing_target_record_deletes_old_association
    assert_no_difference "Membership.count" do
      new_club = Club.create(:name => "Bananarama")
      @member.club = new_club
60
      @member.reload
61 62
    end
  end
63 64 65 66 67 68 69 70

  def test_set_record_to_nil_should_delete_association
    @member.club = nil
    @member.reload
    assert_equal nil, @member.current_membership
    assert_nil @member.club
  end

71 72 73
  def test_has_one_through_polymorphic
    assert_equal clubs(:moustache_club), @member.sponsor_club
  end
74

75
  def test_has_one_through_eager_loading
76 77 78
    members = assert_queries(3) do #base table, through table, clubs table
      Member.find(:all, :include => :club, :conditions => ["name = ?", "Groucho Marx"])
    end
79 80 81
    assert_equal 1, members.size
    assert_not_nil assert_no_queries {members[0].club}
  end
82

83
  def test_has_one_through_eager_loading_through_polymorphic
84 85 86
    members = assert_queries(3) do #base table, through table, clubs table
      Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"])
    end
87
    assert_equal 1, members.size
88
    assert_not_nil assert_no_queries {members[0].sponsor_club}
89 90 91 92 93 94 95 96 97 98 99 100
  end

  def test_has_one_through_polymorphic_with_source_type
    assert_equal members(:groucho), clubs(:moustache_club).sponsored_member
  end

  def test_eager_has_one_through_polymorphic_with_source_type
    clubs = Club.find(:all, :include => :sponsored_member, :conditions => ["name = ?","Moustache and Eyebrow Fancier Club"])
    # Only the eyebrow fanciers club has a sponsored_member
    assert_not_nil assert_no_queries {clubs[0].sponsored_member}
  end

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
  def test_has_one_through_nonpreload_eagerloading
    members = assert_queries(1) do
      Member.find(:all, :include => :club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback
    end
    assert_equal 1, members.size
    assert_not_nil assert_no_queries {members[0].club}
  end

  def test_has_one_through_nonpreload_eager_loading_through_polymorphic
    members = assert_queries(1) do
      Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name') #force fallback
    end
    assert_equal 1, members.size
    assert_not_nil assert_no_queries {members[0].sponsor_club}
  end

117 118 119 120 121 122 123 124 125 126
  def test_has_one_through_nonpreload_eager_loading_through_polymorphic_with_more_than_one_through_record
    Sponsor.new(:sponsor_club => clubs(:crazy_club), :sponsorable => members(:groucho)).save!
    members = assert_queries(1) do
      Member.find(:all, :include => :sponsor_club, :conditions => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name DESC') #force fallback
    end
    assert_equal 1, members.size
    assert_not_nil assert_no_queries { members[0].sponsor_club }
    assert_equal clubs(:crazy_club), members[0].sponsor_club
  end

P
pivotal 已提交
127 128 129 130 131 132 133 134 135
  def test_uninitialized_has_one_through_should_return_nil_for_unsaved_record
    assert_nil Member.new.club
  end

  def test_assigning_association_correctly_assigns_target
    new_member = Member.create(:name => "Chris")
    new_member.club = new_club = Club.create(:name => "LRUG")
    assert_equal new_club, new_member.club.target
  end
136 137

  def test_has_one_through_proxy_should_not_respond_to_private_methods
138 139
    assert_raise(NoMethodError) { clubs(:moustache_club).private_method }
    assert_raise(NoMethodError) { @member.club.private_method }
140 141 142 143 144 145
  end

  def test_has_one_through_proxy_should_respond_to_private_methods_via_send
    clubs(:moustache_club).send(:private_method)
    @member.club.send(:private_method)
  end
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

  def test_assigning_to_has_one_through_preserves_decorated_join_record
    @organization = organizations(:nsa)
    assert_difference 'MemberDetail.count', 1 do
      @member_detail = MemberDetail.new(:extra_data => 'Extra')
      @member.member_detail = @member_detail
      @member.organization = @organization
    end
    assert_equal @organization, @member.organization
    assert @organization.members.include?(@member)
    assert_equal 'Extra', @member.member_detail.extra_data
  end

  def test_reassigning_has_one_through
    @organization = organizations(:nsa)
    @new_organization = organizations(:discordians)

    assert_difference 'MemberDetail.count', 1 do
      @member_detail = MemberDetail.new(:extra_data => 'Extra')
      @member.member_detail = @member_detail
      @member.organization = @organization
    end
    assert_equal @organization, @member.organization
    assert_equal 'Extra', @member.member_detail.extra_data
    assert @organization.members.include?(@member)
    assert !@new_organization.members.include?(@member)

    assert_no_difference 'MemberDetail.count' do
      @member.organization = @new_organization
    end
    assert_equal @new_organization, @member.organization
    assert_equal 'Extra', @member.member_detail.extra_data
    assert !@organization.members.include?(@member)
    assert @new_organization.members.include?(@member)
  end

182 183 184 185 186 187 188 189 190 191 192 193 194 195
  def test_preloading_has_one_through_on_belongs_to
    assert_not_nil @member.member_type
    @organization = organizations(:nsa)
    @member_detail = MemberDetail.new
    @member.member_detail = @member_detail
    @member.organization = @organization
    @member_details = assert_queries(3) do
      MemberDetail.find(:all, :include => :member_type)
    end
    @new_detail = @member_details[0]
    assert @new_detail.loaded_member_type?
    assert_not_nil assert_no_queries { @new_detail.member_type }
  end

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
  def test_save_of_record_with_loaded_has_one_through
    @club = @member.club
    assert_not_nil @club.sponsored_member

    assert_nothing_raised do
      Club.find(@club.id).save!
      Club.find(@club.id, :include => :sponsored_member).save!
    end

    @club.sponsor.destroy

    assert_nothing_raised do
      Club.find(@club.id).save!
      Club.find(@club.id, :include => :sponsored_member).save!
    end
  end
212

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
  def test_through_belongs_to_after_destroy
    @member_detail = MemberDetail.new(:extra_data => 'Extra')
    @member.member_detail = @member_detail
    @member.save!

    assert_not_nil @member_detail.member_type
    @member_detail.destroy
    assert_queries(1) do
      assert_not_nil @member_detail.member_type(true)
    end

    @member_detail.member.destroy
    assert_queries(1) do
      assert_nil @member_detail.member_type(true)
    end
  end

230 231 232 233 234 235
  def test_value_is_properly_quoted
    minivan = Minivan.find('m1')
    assert_nothing_raised do
      minivan.dashboard
    end
  end
236 237

  def test_has_one_through_with_default_scope_on_join_model
238
    assert_equal posts(:welcome).comments.order('id').first, authors(:david).comment_on_first_posts
239
  end
240
end