Skip to content

Commit cd469fd

Browse files
authored
Merge pull request rails#41392 from kddnewton/raise-error-belongs-to-custom-primary-key
Raise error on invalid fixture primary key
2 parents 14540a5 + 006eb25 commit cd469fd

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

activerecord/lib/active_record/fixture_set/table_row.rb

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,29 @@ def timestamp_column_names
3939
end
4040
end
4141

42+
class PrimaryKeyError < StandardError # :nodoc:
43+
def initialize(label, association, value)
44+
super(<<~MSG)
45+
Unable to set #{association.name} to #{value} because the association has a
46+
custom primary key (#{association.join_primary_key}) that does not match the
47+
associated table's primary key (#{association.klass.primary_key}).
48+
49+
To fix this, change your fixture from
50+
51+
#{label}:
52+
#{association.name}: #{value}
53+
54+
to
55+
56+
#{label}:
57+
#{association.foreign_key}: **value**
58+
59+
where **value** is the #{association.join_primary_key} value for the
60+
associated #{association.klass.name} record.
61+
MSG
62+
end
63+
end
64+
4265
def initialize(fixture, table_rows:, label:, now:)
4366
@table_rows = table_rows
4467
@label = label
@@ -119,9 +142,13 @@ def resolve_sti_reflections
119142
fk_name = association.join_foreign_key
120143

121144
if association.name.to_s != fk_name && value = @row.delete(association.name.to_s)
122-
if association.polymorphic? && value.sub!(/\s*\(([^)]*)\)\s*$/, "")
123-
# support polymorphic belongs_to as "label (Type)"
124-
@row[association.join_foreign_type] = $1
145+
if association.polymorphic?
146+
if value.sub!(/\s*\(([^)]*)\)\s*$/, "")
147+
# support polymorphic belongs_to as "label (Type)"
148+
@row[association.join_foreign_type] = $1
149+
end
150+
elsif association.join_primary_key != association.klass.primary_key
151+
raise PrimaryKeyError.new(@label, association, value)
125152
end
126153

127154
fk_type = reflection_class.type_for_attribute(fk_name).type

activerecord/test/cases/fixtures_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "models/admin/account"
77
require "models/admin/randomly_named_c1"
88
require "models/admin/user"
9+
require "models/author"
910
require "models/binary"
1011
require "models/book"
1112
require "models/bulb"
@@ -18,6 +19,7 @@
1819
require "models/developer"
1920
require "models/dog"
2021
require "models/doubloon"
22+
require "models/essay"
2123
require "models/joke"
2224
require "models/matey"
2325
require "models/other_dog"
@@ -1492,6 +1494,16 @@ def self.file_fixture_path
14921494
end
14931495
end
14941496

1497+
class PrimaryKeyErrorTest < ActiveRecord::TestCase
1498+
test "generates the correct value" do
1499+
e = assert_raise(ActiveRecord::FixtureSet::TableRow::PrimaryKeyError) do
1500+
ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT + "/primary_key_error", "primary_key_error")
1501+
end
1502+
1503+
assert_includes e.message, "Unable to set"
1504+
end
1505+
end
1506+
14951507
if current_adapter?(:SQLite3Adapter) && !in_memory_db?
14961508
class MultipleFixtureConnectionsTest < ActiveRecord::TestCase
14971509
include ActiveRecord::TestFixtures
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_fixture:
2+
model_class: Author
3+
4+
david:
5+
name: David
6+
owned_essay: a_modest_proposal

0 commit comments

Comments
 (0)