Skip to content

Commit

Permalink
fix assignment to has_one :through associations.
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Koziarski <michael@koziarski.com>
  • Loading branch information
al2o3cr authored and NZKoz committed Nov 15, 2008
1 parent 31be959 commit d3fd997
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 5 deletions.
Expand Up @@ -8,11 +8,10 @@ def create_through_record(new_value) #nodoc:
current_object = @owner.send(@reflection.through_reflection.name)

if current_object
klass.destroy(current_object)
@owner.clear_association_cache
current_object.update_attributes(construct_join_attributes(new_value))
else
@owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
end

@owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
end

private
Expand Down
Expand Up @@ -3,9 +3,11 @@
require 'models/member'
require 'models/membership'
require 'models/sponsor'
require 'models/organization'
require 'models/member_detail'

class HasOneThroughAssociationsTest < ActiveRecord::TestCase
fixtures :members, :clubs, :memberships, :sponsors
fixtures :members, :clubs, :memberships, :sponsors, :organizations

def setup
@member = members(:groucho)
Expand Down Expand Up @@ -120,4 +122,40 @@ 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

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

end
5 changes: 5 additions & 0 deletions activerecord/test/fixtures/organizations.yml
@@ -0,0 +1,5 @@
nsa:
name: No Such Agency
discordians:
name: Discordians

2 changes: 2 additions & 0 deletions activerecord/test/models/member.rb
Expand Up @@ -6,4 +6,6 @@ class Member < ActiveRecord::Base
has_one :favourite_club, :through => :memberships, :conditions => ["memberships.favourite = ?", true], :source => :club
has_one :sponsor, :as => :sponsorable
has_one :sponsor_club, :through => :sponsor
has_one :member_detail
has_one :organization, :through => :member_detail
end
4 changes: 4 additions & 0 deletions activerecord/test/models/member_detail.rb
@@ -0,0 +1,4 @@
class MemberDetail < ActiveRecord::Base
belongs_to :member
belongs_to :organization
end
4 changes: 4 additions & 0 deletions activerecord/test/models/organization.rb
@@ -0,0 +1,4 @@
class Organization < ActiveRecord::Base
has_many :member_details
has_many :members, :through => :member_details
end
10 changes: 10 additions & 0 deletions activerecord/test/schema/schema.rb
Expand Up @@ -197,6 +197,12 @@ def create_table(*args, &block)
t.string :name
end

create_table :member_details, :force => true do |t|
t.integer :member_id
t.integer :organization_id
t.string :extra_data
end

create_table :memberships, :force => true do |t|
t.datetime :joined_on
t.integer :club_id, :member_id
Expand Down Expand Up @@ -249,6 +255,10 @@ def create_table(*args, &block)
t.integer :shipping_customer_id
end

create_table :organizations, :force => true do |t|
t.string :name
end

create_table :owners, :primary_key => :owner_id ,:force => true do |t|
t.string :name
end
Expand Down

0 comments on commit d3fd997

Please sign in to comment.