Ошибка FactoryGirl, has_one и проверка
Это две простые модели:
class Post < ActiveRecord::Base
has_one :asset, :dependent => :destroy
validates :asset, presence: true
end
class Asset < ActiveRecord::Base
belongs_to :post
end
Я пытаюсь создать factory следующим образом:
factory :post do
# fields...
asset { FactoryGirl.create(:asset) }
end
factory :asset do
# fields...
post
end
Но, запустив spec, он входит в цикл.
Я также попытался это сделать:
factory :post do
# fields...
before(:create) do |post, evaluator|
FactoryGirl.create_list(:asset, 1, post: post)
end
end
Но закончилось "Ошибка проверки: Asset не может быть пустым".
Как я могу представить свою ситуацию?
Ответы
Ответ 1
Я решил эту проблему, используя обратный вызов после (: build).
factory :post do
# fields...
after(:build) do |post|
post.asset ||= FactoryGirl.build(:asset, :post => post)
end
end
factory :asset do
# fields...
after(:build) do |asset|
asset.post ||= FactoryGirl.build(:post, :asset => asset)
end
end
Таким образом, связанные объекты будут созданы до того, как будет сохранен класс владельца, поэтому проверка прошла.
Ответ 2
Проверка не выполняется, поскольку, когда FactoryGirl
создает Post
, должен присутствовать актив. Поэтому в ваших определениях FactoryGirl
вы можете создать Asset
как часть создания Post
. Вставьте что-то вроде файла FactoryGirl post.rb
:
asset { FactoryGirl.create(:asset) }
или
Вы можете создать Asset
как часть вашего объявления Post
в вашем спецификационном файле, например следующее:
asset = FactoryGirl.create(:asset)
FactoryGirl.create(:post, :asset => asset)
Спасибо.
Ответ 3
Вы можете предварительно загрузить дочернюю ассоциацию, передав ее следующим образом:
FactoryGirl.define do
factory :post do
asset { Asset.create! }
end
end
(Лучше, используя Asset factory, чтобы сгенерировать его связанный актив с предварительно заданными настройками).
Другим ручным способом было бы создать Asset через FactoryGirl.create(: asset) и передать его в создание переменной, то есть:
asset = FactoryGirl.create(:asset)
post = FactoryGirl.create(:post, asset: asset)
Ответ 4
ошибка Validation failed: Asset can't be blank
заключается в том, что похоже, что у вас есть связь назад на ваших фабриках.
factory :post do
# fields...
end
Поэтому, когда вы создаете post
, нет asset
, поэтому проверка не выполняется. Попробуйте это
factory :post do
# fields...
asset
end
Посмотрите на эту страницу wiki и раздел ассоциаций. Он также объясняет разницу между create
и build
с ассоциациями