has_one_through_associations_test.rb 7.5 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

class HasOneThroughAssociationsTest < ActiveRecord::TestCase
14
  fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, :dashboards, :speedometers
15

16 17 18 19 20 21 22 23 24 25 26
  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
27

28 29 30 31 32 33
  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
34 35 36 37 38 39 40 41 42 43

  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
44

45 46 47 48 49 50
  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
51

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

  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

67 68 69
  def test_has_one_through_polymorphic
    assert_equal clubs(:moustache_club), @member.sponsor_club
  end
70

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

79
  def test_has_one_through_eager_loading_through_polymorphic
80 81 82
    members = assert_queries(3) do #base table, through table, clubs table
      Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"])
    end
83
    assert_equal 1, members.size
84
    assert_not_nil assert_no_queries {members[0].sponsor_club}
85 86 87 88 89 90 91 92 93 94 95 96
  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

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  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

113 114 115 116 117 118 119 120 121 122
  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 已提交
123 124 125 126 127 128 129 130 131
  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
132 133

  def test_has_one_through_proxy_should_not_respond_to_private_methods
134 135
    assert_raise(NoMethodError) { clubs(:moustache_club).private_method }
    assert_raise(NoMethodError) { @member.club.private_method }
136 137 138 139 140 141
  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
142 143 144 145 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

  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

178 179 180 181 182 183 184 185 186 187 188 189 190 191
  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

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  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
208

209 210 211 212 213 214
  def test_value_is_properly_quoted
    minivan = Minivan.find('m1')
    assert_nothing_raised do
      minivan.dashboard
    end
  end
215
end