aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzymon Nowak <szimek@gmail.com>2009-08-13 21:18:43 +0200
committerAaron Patterson <aaron.patterson@gmail.com>2010-12-23 15:19:17 -0800
commit85683f2a79dbf81130361cb6426786cf6b0d1925 (patch)
treec802a675983c3a7cb9d3a31ae8adf63d1baca0ca
parentb79823832e6cd30a9f14f97ffdf1642d4d63d4ea (diff)
downloadrails-85683f2a79dbf81130361cb6426786cf6b0d1925.tar.gz
rails-85683f2a79dbf81130361cb6426786cf6b0d1925.tar.bz2
rails-85683f2a79dbf81130361cb6426786cf6b0d1925.zip
Fix creation of has_many through records with custom primary_key option on belongs_to [#2990 state:resolved]
-rw-r--r--activerecord/lib/active_record/associations/through_association_scope.rb7
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb30
-rw-r--r--activerecord/test/models/author.rb1
-rw-r--r--activerecord/test/models/categorization.rb1
-rw-r--r--activerecord/test/schema/schema.rb1
5 files changed, 38 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb
index 5dc5b0c048..99920d4c63 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association_scope.rb
@@ -106,7 +106,12 @@ module ActiveRecord
# TODO: revisit this to allow it for deletion, supposing dependent option is supported
raise ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(@owner, @reflection) if [:has_one, :has_many].include?(@reflection.source_reflection.macro)
- join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
+ join_attributes = construct_owner_attributes(@reflection.through_reflection)
+
+ join_attributes.merge!(
+ @reflection.source_reflection.primary_key_name =>
+ associate.send(@reflection.source_reflection.association_primary_key)
+ )
if @reflection.options[:source_type]
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name)
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 816b43ab9e..d237273464 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -21,7 +21,7 @@ require 'models/categorization'
require 'models/category'
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :posts, :readers, :people, :comments, :authors,
+ fixtures :posts, :readers, :people, :comments, :authors, :categories,
:owners, :pets, :toys, :jobs, :references, :companies,
:subscribers, :books, :subscriptions, :developers, :categorizations
@@ -397,6 +397,34 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal people(:susan).agents.map(&:agents).flatten, people(:susan).agents_of_agents
end
+ def test_associate_existing_with_nonstandard_primary_key_on_belongs_to
+ Categorization.create(:author => authors(:mary), :named_category_name => categories(:general).name)
+ assert_equal categories(:general), authors(:mary).named_categories.first
+ end
+
+ def test_collection_build_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.build(:name => "Primary")
+ author.save
+ assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).include?(category)
+ end
+
+ def test_collection_create_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.create(:name => "Primary")
+ assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).include?(category)
+ end
+
+ def test_collection_delete_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.create(:name => "Primary")
+ author.named_categories.delete(category)
+ assert !Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).empty?
+ end
+
def test_collection_singular_ids_getter_with_string_primary_keys
book = books(:awdr)
assert_equal 2, book.subscriber_ids.size
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index 244c5ac4f5..83a6f5d926 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -78,6 +78,7 @@ class Author < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
+ has_many :named_categories, :through => :categorizations
has_many :special_categorizations
has_many :special_categories, :through => :special_categorizations, :source => :category
diff --git a/activerecord/test/models/categorization.rb b/activerecord/test/models/categorization.rb
index fdb0a11540..45f50e4af3 100644
--- a/activerecord/test/models/categorization.rb
+++ b/activerecord/test/models/categorization.rb
@@ -1,6 +1,7 @@
class Categorization < ActiveRecord::Base
belongs_to :post
belongs_to :category
+ belongs_to :named_category, :class_name => 'Category', :foreign_key => :named_category_name, :primary_key => :name
belongs_to :author
belongs_to :author_using_custom_pk, :class_name => 'Author', :foreign_key => :author_id, :primary_key => :author_address_extra_id
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 99761a4160..3dea7e1492 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -110,6 +110,7 @@ ActiveRecord::Schema.define do
create_table :categorizations, :force => true do |t|
t.column :category_id, :integer
+ t.string :named_category_name
t.column :post_id, :integer
t.column :author_id, :integer
t.column :special, :boolean