FactoryBot - 覆盖与特征的关联
FactoryBot - Override association with trait
假设我有几个模型,sport 和 player,其中 player belongs_to
sport 和 sport has_many
players。然后我为这两个创建工厂如下:
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
相关联,而是 returns:
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
相关联
我想你想要:
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
假设我有几个模型,sport 和 player,其中 player belongs_to
sport 和 sport has_many
players。然后我为这两个创建工厂如下:
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
相关联,而是 returns:
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
相关联
我想你想要:
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