分配已存在的关联的正确方法是什么?
我正在尝试在用户和城市之间分配一个has_one关系,其中许多用户或其他实体(例如某个事件)可以使用同一个城市。
代码
FactoryGirl.define do
factory :user do
name 'john'
trait :in_boston do
association :city, factory: :boston
end
end
end
错误
PG :: UniqueViolation:错误:重复的键值违反了唯一约束“city_pkey”,因为它试图在数据库中创建两次波士顿。
我想做的只是参考现有工厂,而不是创建一个新工厂。
我当前的工作(但不太理想)解决方案
FactoryGirl.define do
factory :user do
name 'john'
trait :in_boston do
after(:create) do |user|
user.city = City.find_by_name('Boston') || create(:boston)
end
end
end
end
任何指导都将不胜感激,谢谢。
答案 0 :(得分:1)
所以,我将假设您的模型代码是黄金的,并向您展示我如何设置测试。我不确定为什么你需要工厂根据城市是否存在来拥有决策权。只需在自己的工厂中实例化城市,并在测试设置中调用该关联。
工厂
# factories/cities.rb
FactoryGirl.define do
factory :city do
name 'Boston'
end
end
# factories/users.rb
FactoryGirl.define do
factory :user do
name 'john'
city
end
end
测试
describe 'blah' do
let( :city ){ create :city }
let( :user ){ create :user, city: city }
it 'user should have a city' do
expect( user.city.name ).to eq 'Boston'
end
end
答案 1 :(得分:0)
当回调创建该关联时,测试属于另一个模型的模型时,我遇到了相同的问题。
为了简单地说明,假设我有一个Book
模型和一个Page
模型,其中有Page belongs_to Book
,并且有一个在创建图书时创建Page
的回调
在我的工厂Page
中,我尝试与Book
关联,但是这样做一次,我创建了一本书,而页面的创建本身又在创建了同一本书。根据UniqueIndex条件,PostgreSQL失败。
在这种情况下,最简单的解决方案是在测试Page模型时不创建Page
,而是简单地create(:book)
然后使用book.page
。