我有一个数据模型,其中
account
在子域上具有唯一的验证。
我的大多数其他对象都与
account
对象相关联。
在我的数据模型中,
product
有一个account_id
和一个program_id
在 FactoryBot 中我想写一些类似的东西:
create(:product, :with_program, account: account)
然后使用该特定帐户创建所有关联的资源。
在我的
product
工厂:
FactoryBot.define do
factory :product do
association :account
association :program
trait :with_program do
after_build do |product|
product.program = create(
:program,
:with_author,
account: product.account
)
end
end
end
end
然而,这会直接创建程序,该程序又会重新创建帐户,并触发帐户的唯一性验证。
FactoryBot.define do
factory :program do
association :account
end
end
到目前为止,我发现的唯一解决方案是在创建实际产品之前创建产品所依赖的所有关联并将其传递给
create method
:
let(:program) do
create(
:program,
:with_future_start_date_sessions,
account: account,
author: author
)
end
create(
:product,
:draft,
program: program,
account: account
)
end
有没有更聪明的方法将
account
传递给所有 product
关联并在 trait
或类似的东西中创建它们?
在创建复杂的关联时,我总是喜欢采用自上而下的方法。不要使用帐户创建产品,而是尝试使用产品创建帐户,这样您就不需要事先创建关联。
FactoryBot.define do
factory :account do
# account attributes...
trait :with_products do
transient do
product_count {2}
end
after(:build, :create) do |account, evaluator|
create_list(
:product,
evaluator.product_count,
:with_program,
account: account
)
end
end
end
end
然后您可以通过调用来创建产品
# 1 account, 5 products
FactoryBot::create(:account, :with_products, product_count: 5)
# 5 accounts with 1 product each
FactoryBot::create_list(:account, 5, :with_products, product_count: 1)
我不确定这是否有帮助,但我做了这样的事情。我对相关模型进行了各种验证,这样构建和创建工厂都有效:
FactoryBot.define do
factory :product do
account(:build) do |product|
product.program ||= build(:program)
product.account ||= build(:account)
end
after(:create) do |product|
product.program.save!
product.account.save!
end
end
end