mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
fix assignment to has_one :through associations.
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
committed by
Michael Koziarski
parent
31be959de7
commit
d3fd997109
@@ -8,11 +8,10 @@ module ActiveRecord
|
||||
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
|
||||
|
||||
@@ -3,9 +3,11 @@ require 'models/club'
|
||||
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)
|
||||
@@ -120,4 +122,40 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
|
||||
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
activerecord/test/fixtures/organizations.yml
vendored
Normal file
5
activerecord/test/fixtures/organizations.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
nsa:
|
||||
name: No Such Agency
|
||||
discordians:
|
||||
name: Discordians
|
||||
|
||||
@@ -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
activerecord/test/models/member_detail.rb
Normal file
4
activerecord/test/models/member_detail.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class MemberDetail < ActiveRecord::Base
|
||||
belongs_to :member
|
||||
belongs_to :organization
|
||||
end
|
||||
4
activerecord/test/models/organization.rb
Normal file
4
activerecord/test/models/organization.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class Organization < ActiveRecord::Base
|
||||
has_many :member_details
|
||||
has_many :members, :through => :member_details
|
||||
end
|
||||
@@ -197,6 +197,12 @@ ActiveRecord::Schema.define do
|
||||
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
|
||||
@@ -249,6 +255,10 @@ ActiveRecord::Schema.define do
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user