Skip to content

Commit 9b9b24f

Browse files
pbolingalexandreruban
authored andcommitted
Support uuid primary keys in build_stubbed
fixes thoughtbot#1498 closes thoughtbot#1514 Co-authored-by: Alexandre Ruban <[email protected]>
1 parent 8f4f899 commit 9b9b24f

File tree

2 files changed

+71
-22
lines changed

2 files changed

+71
-22
lines changed

lib/factory_bot/strategy/stub.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ def to_sym
4747

4848
private
4949

50-
def next_id
51-
@@next_id += 1
50+
def next_id(result_instance)
51+
if uuid_primary_key?(result_instance)
52+
SecureRandom.uuid
53+
else
54+
@@next_id += 1
55+
end
5256
end
5357

5458
def stub_database_interaction_on_result(result_instance)
5559
if has_settable_id?(result_instance)
56-
result_instance.id ||= next_id
60+
result_instance.id ||= next_id(result_instance)
5761
end
5862

5963
result_instance.instance_eval do
@@ -83,6 +87,13 @@ def has_settable_id?(result_instance)
8387
result_instance.class.primary_key
8488
end
8589

90+
def uuid_primary_key?(result_instance)
91+
result_instance.respond_to?(:column_for_attribute) &&
92+
(column = result_instance.column_for_attribute(result_instance.class.primary_key)) &&
93+
column.respond_to?(:sql_type) &&
94+
column.sql_type == "uuid"
95+
end
96+
8697
def clear_changes_information(result_instance)
8798
if result_instance.respond_to?(:clear_changes_information)
8899
result_instance.clear_changes_information

spec/acceptance/stub_spec.rb

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,43 +59,81 @@
5959
end
6060
end
6161

62-
describe "a stubbed instance with no primary key" do
63-
it "builds a stubbed instance" do
64-
using_model_without_pk do
65-
FactoryBot.define do
66-
factory :model_without_pk
62+
describe "overridden primary keys conventions" do
63+
describe "a stubbed instance with a uuid primary key" do
64+
it "builds a stubbed instance" do
65+
using_model("ModelWithUuid", primary_key: :uuid) do
66+
FactoryBot.define do
67+
factory :model_with_uuid
68+
end
69+
70+
model = FactoryBot.build_stubbed(:model_with_uuid)
71+
expect(model).to be_truthy
6772
end
73+
end
74+
75+
it "behaves like a persisted record" do
76+
using_model("ModelWithUuid", primary_key: :uuid) do
77+
FactoryBot.define do
78+
factory :model_with_uuid
79+
end
6880

69-
model = FactoryBot.build_stubbed(:model_without_pk)
70-
expect(model).to be_truthy
81+
model = FactoryBot.build_stubbed(:model_with_uuid)
82+
expect(model).to be_persisted
83+
expect(model).not_to be_new_record
84+
end
85+
end
86+
87+
it "has a uuid primary key" do
88+
using_model("ModelWithUuid", primary_key: :uuid) do
89+
FactoryBot.define do
90+
factory :model_with_uuid
91+
end
92+
93+
model = FactoryBot.build_stubbed(:model_with_uuid)
94+
expect(model.id).to be_a(String)
95+
end
7196
end
7297
end
7398

74-
it "behaves like a persisted record" do
75-
using_model_without_pk do
76-
FactoryBot.define do
77-
factory :model_without_pk
99+
describe "a stubbed instance with no primary key" do
100+
it "builds a stubbed instance" do
101+
using_model("ModelWithoutPk", primary_key: false) do
102+
FactoryBot.define do
103+
factory :model_without_pk
104+
end
105+
106+
model = FactoryBot.build_stubbed(:model_without_pk)
107+
expect(model).to be_truthy
78108
end
109+
end
79110

80-
model = FactoryBot.build_stubbed(:model_without_pk)
81-
expect(model).to be_persisted
82-
expect(model).not_to be_new_record
111+
it "behaves like a persisted record" do
112+
using_model("ModelWithoutPk", primary_key: false) do
113+
FactoryBot.define do
114+
factory :model_without_pk
115+
end
116+
117+
model = FactoryBot.build_stubbed(:model_without_pk)
118+
expect(model).to be_persisted
119+
expect(model).not_to be_new_record
120+
end
83121
end
84122
end
85123

86-
def using_model_without_pk
87-
define_class("ModelWithoutPk", ActiveRecord::Base)
124+
def using_model(name, primary_key:)
125+
define_class(name, ActiveRecord::Base)
88126

89127
connection = ActiveRecord::Base.connection
90128
begin
91-
clear_generated_table("model_without_pks")
92-
connection.create_table("model_without_pks", id: false) do |t|
129+
clear_generated_table(name.tableize)
130+
connection.create_table(name.tableize, id: primary_key) do |t|
93131
t.column :updated_at, :datetime
94132
end
95133

96134
yield
97135
ensure
98-
clear_generated_table("model_without_pks")
136+
clear_generated_table(name.tableize)
99137
end
100138
end
101139
end

0 commit comments

Comments
 (0)