假设我有几个模特,运动和运动员,其中有belongs_to
运动员和运动has_many
运动员。然后,我为这两个创建工厂,如下所示:
FactoryBot.define do
factory :player do
name "John Doe"
sport
trait :with_existing_sport do
transient do
sport Sport.last
end
sport { with_existing_sport }
end
end
end
FactoryBot.define do
factory :sport do
name "football"
end
end
当我打开rails控制台并运行FactoryBot.create(:player)
时,它可以正常工作并在数据库中创建一个新的播放器和相关的运动。但是当我运行FactoryBot.create(:player, :with_existing_sport)
时,我希望它能够创建播放器,然后将该播放器与Sport.last
相关联,但它会返回:
FactoryBot::AttributeDefinitionError: Attribute already defined: sport
总而言之,我想要完成的是能够:
FactoryBot.create(:player)
应创建一个玩家和一项运动FactoryBot.create(:player, :with_existing_sport)
应该创建一个播放器并使其属于Sport.last
FactoryBot.create(:player, with_existing_sport: Sport.first)
应该创建一个播放器并使其属于Sport.first
有办法做到这一点吗?我在文档中找不到任何内容。
*编辑*
溶液
感谢Marlin Pierce,我最终得到了这样的工作:
FactoryBot.define do
factory :player do
name "John Doe"
sport
trait :with_existing_sport do
transient do
associated_sport Sport.last
end
sport { associated_sport }
end
end
end
FactoryBot.define do
factory :sport do
name "football"
end
end
现在我可以按如下方式使用工厂:
FactoryBot.create(:player)
,它将创建一个玩家,并且它是相关的运动FactoryBot.create(:player, :with_existing_sport)
将创建播放器并将其与Sport.last
FactoryBot.create(:player, :with_existing_sport, associated_sport: Sport.find_by(name: "football"))
会将其与associated_sport
答案 0 :(得分:2)
我想你想要:
FactoryBot.define do
factory :player do
name "John Doe"
sport
trait :with_existing_sport do
sport { Sport.last }
end
end
end
如果您确实需要瞬态属性,则应将其重命名为与非瞬态字段不同的内容。
trait :with_existing_sport do
transient do
sport_trans Sport.last
end
sport { sport_trans }
end