mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Fix belongs_to polymorphic with custom primary key on target.
Closes #3104.
This commit is contained in:
@@ -68,7 +68,12 @@ module ActiveRecord
|
||||
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 @@ module ActiveRecord
|
||||
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?
|
||||
|
||||
@@ -223,11 +223,9 @@ module ActiveRecord
|
||||
@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
|
||||
@@ -475,17 +473,15 @@ module ActiveRecord
|
||||
# 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/comment'
|
||||
require 'models/sponsor'
|
||||
require 'models/member'
|
||||
require 'models/essay'
|
||||
require 'models/toy'
|
||||
|
||||
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
||||
fixtures :accounts, :companies, :developers, :projects, :topics,
|
||||
@@ -687,4 +688,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
||||
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 @@ class ReflectionTest < ActiveRecord::TestCase
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user