如何在其他对象中创建对象?

问题描述 投票:0回答:2

我想创建一个“帖子”和一个“卡片”,但是要创建一张卡片,它必须有 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
ruby-on-rails factory-bot
2个回答
0
投票

我以前没怎么用过

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

0
投票

理想情况下,如果您的测试需要为其自身创建一个定义良好的 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) }
© www.soinside.com 2019 - 2024. All rights reserved.