我想创建一个“帖子”和一个“卡片”,但是要创建一张卡片,它必须有 company_id
factory :post do
first_title { Faker::Name.name }
sub_title { Faker::Name.name }
email { Faker::Internet.email }
company_id {}
card { FactoryBot.create(:card, company_id: company_id) }
end
但是我收到这个错误:
undefined local variable or method `company_id' for #<FactoryBot::SyntaxRunner:0x00007f629fb1b260
我以前没怎么用过
FactoryBot
。但是当查看docs然后我会尝试这个:
factory :post do
first_title { Faker::Name.name }
sub_title { Faker::Name.name }
email { Faker::Internet.email }
company
card { association :card, country: country }
end
或者您可以向您的
Card
模型添加回调以将country
自动设置为相关帖子的国家/地区,如下所示:
# in app/models/card.rb
before_validation :set_country
private
def set_country
self.country = post&.country
end
理想情况下,如果您的测试需要为其自身创建一个定义良好的 ocntext 而不是依赖于工厂行为,那么您应该调用工厂,将关联对象作为参数传递给每个工厂调用。
但是如果你真的想使用 id 来实现这个,你可以使用瞬态属性。
使用
card
对象:
let(:company) { FactoryBot.create :company }
let(:card) { FactoryBot.create(:card, company: company) }
let!(:post) { FactoryBot.create(:post, card: card) }
使用transient属性:
# factory:
factory :post do
first_title { Faker::Name.name }
sub_title { Faker::Name.name }
email { Faker::Internet.email }
transient do
company_id { FactoryBot.create(:company).id }
end
after(:build) do |post, evaluator|
card = FactoryBot.create(:card, evaluator.company_id)
post.card = card
end
end
# spec:
let(:company) { FactoryBot.create :company }
let!(:post) { FactoryBot.create(:post, company_id: company.id) }