如何指定与factory_bot的关联?

38
例如,我有两个模型,一个是用户(user),另一个是帖子(post)。一篇帖子(post)属于一个用户(user),而一个用户(user)可以拥有多篇帖子(posts)。

例如,我有两个模型,一个用户(user)和一个帖子(post)。一篇帖子(post)belongs_to一个用户(user),而一个用户(user)has_many帖子(posts)

#spec/factories/post.rb
FactoryBot.define do
  factory :post do
    user
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

#spec/factories/user.rb
FactoryBot.define do 
  factory :user do 
    first_name 'Jake'
  end
end

在一个测试中使用Rspec,我想要做到这一点:

user = create(:user, first_name: 'Barry') #id 1
post = create(:post, user: user)

我本来期望这篇文章的用户ID是1,然而在创建之前它却创建了另一个用户,导致用户ID变成了2。

当你使用factory_bot / factory_girl创建对象时,如何指定关联?


在你发表帖子后,post.user.inspectUser.all会返回什么? - abax
post.user 是 User。 - Jake McAllister
你能发布完整的规格说明吗?你是否涉及任何身份验证?如果你必须登录才能运行规格说明,那可能是其他用户的来源。 - Petercopter
还有,记录中的 first_names 是什么?它们都是 Jake 吗? - Petercopter
不,这只是一个简单的规范。 - Jake McAllister
显示剩余3条评论
3个回答

46

2
使用显式关联而不是隐式关联的理由还有哪些参数吗? - Ri1a
3
使用显式关联是能够覆盖关联对象属性的唯一方法。当关联是隐式的时,FactoryBot将创建一个关联对象,你无法控制其属性(它将根据该对象的工厂自动创建一个关联对象)。 - Fran Martinez

11

另一种选择是在父级中使用#trait方法。

FactoryBot.define do
  factory :post do
    user nil
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

FactoryBot.define do 
  factory :user do 
    first_name 'Jake'
  end

  trait :with_post do
    after(:create) do |user|
      create(:post, user_id: user.id)
    end
  end
end

FactoryBot.create(:user, :with_post)

8

如果你的关联名称和工厂名称不同,那么可以采用以下语法解决问题。

#spec/factories/post.rb
FactoryBot.define do
  factory :post do
    association :author, factory: :user
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

如果您的工厂名称为“author”,模型名称为“user”,那么您可以使用上述语法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接