I want to create a 'post' and a 'card', but to create an card its necessary have 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
But i am getting this error:
undefined local variable or method `company_id' for #<FactoryBot::SyntaxRunner:0x00007f629fb1b260
Ideally if your test needs to create a well defined ocntext for it self and not rely on the factories behaviour, so you should call the factories passing the associated objects as a param for each factory call.
But if you really want to achieve this using the id you can use transient attributes.
Using the card
object:
factory :company do
# whatever you need here
end
factory :card do
company
end
factory :post do
first_title { Faker::Name.name }
sub_title { Faker::Name.name }
email { Faker::Internet.email }
card
end
let(:company) { FactoryBot.create :company }
let(:card) { FactoryBot.create(:card, company: company) }
let!(:post) { FactoryBot.create(:post, card: card) }
Using the transient attribute:
# 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, company_id: evaluator.company_id)
post.card = card
end
end
# spec:
let(:company) { FactoryBot.create :company }
let!(:post) { FactoryBot.create(:post, company_id: company.id) }
Update: I have added a code for the factories in the first example