From f0b98050296b57d95dbc789f8e52fa82499d151a Mon Sep 17 00:00:00 2001
From: Jon Leighton <j@jonathanleighton.com>
Date: Mon, 14 Feb 2011 20:39:51 +0000
Subject: Ensure that association_ids uses the correct attribute where the
 association is a has_many :through with a :primary_key option on the source
 reflection. [#6376 state:resolved]

---
 activerecord/lib/active_record/associations.rb                 |  7 +++++--
 activerecord/lib/active_record/reflection.rb                   |  4 ++++
 .../cases/associations/has_many_through_associations_test.rb   | 10 ++++++++++
 activerecord/test/models/post.rb                               |  1 +
 4 files changed, 20 insertions(+), 2 deletions(-)

(limited to 'activerecord')

diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index a2db592c7d..529d8ca2d3 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1582,9 +1582,12 @@ module ActiveRecord
 
           redefine_method("#{reflection.name.to_s.singularize}_ids") do
             if send(reflection.name).loaded? || reflection.options[:finder_sql]
-              send(reflection.name).map { |r| r.id }
+              records = send(reflection.name)
+              records.map { |r| r.send(reflection.association_primary_key) }
             else
-              send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map! { |r| r.id }
+              column  = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
+              records = send(reflection.name).select(column).except(:includes)
+              records.map! { |r| r.send(reflection.association_primary_key) }
             end
           end
         end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index ceeb0ec39d..0a0e8d650c 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -394,6 +394,10 @@ module ActiveRecord
         @source_reflection_names ||= (options[:source] ? [options[:source]] : [name.to_s.singularize, name]).collect { |n| n.to_sym }
       end
 
+      def association_primary_key
+        source_reflection.association_primary_key
+      end
+
       def check_validity!
         if through_reflection.nil?
           raise HasManyThroughAssociationNotFoundError.new(active_record.name, self)
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 73b1d6c500..7e77539fe7 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -718,4 +718,14 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
     assert_equal post.tags, post.interpolated_tags
     assert_equal post.tags, post.interpolated_tags_2
   end
+
+  def test_primary_key_option_on_source
+    post     = posts(:welcome)
+    category = categories(:general)
+    categorization = Categorization.create!(:post_id => post.id, :named_category_name => category.name)
+
+    assert_equal [category], post.named_categories
+    assert_equal [category.name], post.named_category_ids # checks when target loaded
+    assert_equal [category.name], post.reload.named_category_ids # checks when target no loaded
+  end
 end
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 5f29196790..1bbcab3a39 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -90,6 +90,7 @@ class Post < ActiveRecord::Base
   has_many :standard_categorizations, :class_name => 'Categorization', :foreign_key => :post_id
   has_many :author_using_custom_pk,  :through => :standard_categorizations
   has_many :authors_using_custom_pk, :through => :standard_categorizations
+  has_many :named_categories, :through => :standard_categorizations
 
   has_many :readers
   has_many :readers_with_person, :include => :person, :class_name => "Reader"
-- 
cgit v1.2.3