提交 3b87c38d 编写于 作者: J Jon Leighton

Fix belongs_to polymorphic with custom primary key on target.

Closes #3104.
上级 5c0e9333
......@@ -68,7 +68,12 @@ def add_constraints(scope)
end
if reflection.source_macro == :belongs_to
key = reflection.association_primary_key
if reflection.options[:polymorphic]
key = reflection.association_primary_key(klass)
else
key = reflection.association_primary_key
end
foreign_key = reflection.foreign_key
else
key = reflection.foreign_key
......
......@@ -45,7 +45,11 @@ def different_target?(record)
end
def replace_keys(record)
owner[reflection.foreign_key] = record && record[reflection.association_primary_key]
if record
owner[reflection.foreign_key] = record[reflection.association_primary_key(record.class)]
else
owner[reflection.foreign_key] = nil
end
end
def foreign_key_present?
......
......@@ -211,11 +211,9 @@ def association_foreign_key
@association_foreign_key ||= options[:association_foreign_key] || class_name.foreign_key
end
def association_primary_key
@association_primary_key ||=
options[:primary_key] ||
!options[:polymorphic] && klass.primary_key ||
'id'
# klass option is necessary to support loading polymorphic associations
def association_primary_key(klass = self.klass)
options[:primary_key] || klass.primary_key
end
def active_record_primary_key
......@@ -463,17 +461,15 @@ def nested?
# We want to use the klass from this reflection, rather than just delegate straight to
# the source_reflection, because the source_reflection may be polymorphic. We still
# need to respect the source_reflection's :primary_key option, though.
def association_primary_key
@association_primary_key ||= begin
# Get the "actual" source reflection if the immediate source reflection has a
# source reflection itself
source_reflection = self.source_reflection
while source_reflection.source_reflection
source_reflection = source_reflection.source_reflection
end
source_reflection.options[:primary_key] || klass.primary_key
def association_primary_key(klass = self.klass)
# Get the "actual" source reflection if the immediate source reflection has a
# source reflection itself
source_reflection = self.source_reflection
while source_reflection.source_reflection
source_reflection = source_reflection.source_reflection
end
source_reflection.options[:primary_key] || klass.primary_key
end
# Gets an array of possible <tt>:through</tt> source reflection names:
......
......@@ -13,6 +13,7 @@
require 'models/sponsor'
require 'models/member'
require 'models/essay'
require 'models/toy'
class BelongsToAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
......@@ -696,4 +697,11 @@ def test_self_referential_belongs_to_with_counter_cache_assigning_nil
assert_equal nil, comment.reload.parent
assert_equal 0, comments(:greetings).reload.children_count
end
def test_polymorphic_with_custom_primary_key
toy = Toy.create!
sponsor = Sponsor.create!(:sponsorable => toy)
assert_equal toy, sponsor.reload.sponsorable
end
end
......@@ -244,7 +244,6 @@ def test_association_primary_key
# Normal association
assert_equal "id", Author.reflect_on_association(:posts).association_primary_key.to_s
assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s
assert_equal "id", Tagging.reflect_on_association(:taggable).association_primary_key.to_s
# Through association (uses the :primary_key option from the source reflection)
assert_equal "nick", Author.reflect_on_association(:subscribers).association_primary_key.to_s
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册