Ошибка повторного ключа ассоциации FactoryGirl
Как правильно назначить ассоциации, которые уже существуют?
Я пытаюсь назначить отношение 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
Любое руководство будет оценено, спасибо.
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
У меня была такая же проблема при тестировании модели, которая принадлежала другой модели, когда обратный вызов создавал эту связь.
Проще говоря, скажем, у меня есть Book
модель, а Page
модель, с Page belongs_to Book
и обратный вызов для создания Page
когда создается книга.
На моей фабрике для Page
, Я пытаюсь ассоциироваться с Book
, но при этом я создаю книгу один раз, а создание самой страницы снова создает ту же книгу. По условию UniqueIndex PostgreSQL не работает.
Самое простое решение в этом случае - не создавать Page
при тестировании модели страницы, а вместо этого просто create(:book)
а затем используйте book.page
.