Skip to content

Commit f8b53f3

Browse files
paneqjosevalim
authored andcommitted
test and fix collection_singular_ids= with string primary keys [rails#5125 state:resolved]
Signed-off-by: José Valim <[email protected]>
1 parent 558ee6e commit f8b53f3

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

activerecord/lib/active_record/associations.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,9 @@ def collection_accessor_methods(reflection, association_proxy_class, writer = tr
14391439
end
14401440

14411441
redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
1442-
ids = (new_value || []).reject { |nid| nid.blank? }.map(&:to_i)
1442+
pk_column = reflection.klass.columns.find{|c| c.name == reflection.klass.primary_key }
1443+
ids = (new_value || []).reject { |nid| nid.blank? }
1444+
ids.map!{|i| pk_column.type_cast(i)}
14431445
send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids))
14441446
end
14451447
end

activerecord/test/cases/associations/has_many_through_associations_test.rb

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@
1414
require 'models/contract'
1515
require 'models/company'
1616
require 'models/developer'
17+
require 'models/subscriber'
18+
require 'models/book'
19+
require 'models/subscription'
1720

1821
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
19-
fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references, :companies
22+
fixtures :posts, :readers, :people, :comments, :authors,
23+
:owners, :pets, :toys, :jobs, :references, :companies,
24+
:subscribers, :books, :subscriptions
2025

2126
# Dummies to force column loads so query counts are clean.
2227
def setup
@@ -383,4 +388,37 @@ def test_modifying_has_many_through_has_one_reflection_should_raise
383388
lambda { authors(:david).very_special_comments.delete(authors(:david).very_special_comments.first) },
384389
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
385390
end
391+
392+
def test_collection_singular_ids_getter_with_string_primary_keys
393+
book = books(:awdr)
394+
assert_equal 2, book.subscriber_ids.size
395+
assert_equal [subscribers(:first).nick, subscribers(:second).nick].sort, book.subscriber_ids.sort
396+
end
397+
398+
def test_collection_singular_ids_setter
399+
company = companies(:rails_core)
400+
dev = Developer.find(:first)
401+
402+
company.developer_ids = [dev.id]
403+
assert_equal [dev], company.developers
404+
end
405+
406+
def test_collection_singular_ids_setter_with_string_primary_keys
407+
assert_nothing_raised do
408+
book = books(:awdr)
409+
book.subscriber_ids = [subscribers(:second).nick]
410+
assert_equal [subscribers(:second)], book.subscribers(true)
411+
412+
book.subscriber_ids = []
413+
assert_equal [], book.subscribers(true)
414+
end
415+
416+
end
417+
418+
def test_collection_singular_ids_setter_raises_exception_when_invalid_ids_set
419+
company = companies(:rails_core)
420+
ids = [Developer.find(:first).id, -9999]
421+
assert_raises(ActiveRecord::RecordNotFound) {company.developer_ids= ids}
422+
end
423+
386424
end

activerecord/test/fixtures/subscriptions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ webster_rfr:
99
alterself_awdr:
1010
id: 3
1111
subscriber_id: alterself
12-
book_id: 3
12+
book_id: 1

activerecord/test/models/book.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
class Book < ActiveRecord::Base
22
has_many :citations, :foreign_key => 'book1_id'
33
has_many :references, :through => :citations, :source => :reference_of, :uniq => true
4+
5+
has_many :subscriptions
6+
has_many :subscribers, :through => :subscriptions
47
end

0 commit comments

Comments
 (0)