使用'默认' FactoryGirl中的特征,以避免不必要的关联创建

时间:2015-06-14 13:37:05

标签: ruby-on-rails factory-bot

是否可以在FactoryGirl中定义默认特征?如果我定义这样的工厂(其中question_response属于问题):

factory :question_response do
  question
  work_history

  trait :open do
    question { FactoryGirl.create :question, question_type: 'open' }
  end
end

当我FactoryGirl.create :question_response, :open时,它将首先创建一个默认问题,然后在特征内创建另一个问题,这是一个不必要的操作。

理想情况下,我想这样做:

factory :question_response do
  work_history

  trait :default do
    question { FactoryGirl.create :question, question_type: 'yes_no' }
  end

  trait :open do
    question { FactoryGirl.create :question, question_type: 'open' }
  end
end

然后执行FactoryGirl.create :question将使用默认特征,但它似乎不可能。

3 个答案:

答案 0 :(得分:2)

  

当我做FactoryGirl.create:question_response时,:打开它会先创建一个默认问题,然后在特质内创建另一个

这不是真的。如果您使用question指定特征,它将在创建之前覆盖工厂行为,以便它不会创建默认问题。

我用FactoryGirl v4.5.0检查了它

答案 1 :(得分:0)

您的特性正在创建第二条记录,因为您有一个创建记录的块:

trait :open do
  question { FactoryGirl.create :question, question_type: 'open' }
end

相反,你可以在问题类型设置的问题上定义一个特征,然后让你的question_response使用该问题,并将open trait作为默认值。

factory.define :question do
  trait :open do
    question_type 'open'
  end
end

factory.define :question_response do
  association :question, :open
end

答案 2 :(得分:0)

以防万一其他人正在寻找“默认特征”场景,我们在https://github.com/thoughtbot/factory_bot/issues/528#issuecomment-18289143中用示例进行了讨论

基本上,您可以使用默认值定义特征,然后将其用于不同的工厂。然后,您可以使用具有所需配置的适当工厂。

例如:

FactoryBot.define do
  trait :user_defaults do
    email { Faker::Internet.unique.email }
    username { Faker::Internet.unique.username }
    password { "test1234" }
  end

  factory :with_admin_role, class: User do
    user_defaults

    after(:create) do |user, _|
      user.add_role :admin
    end
  end

  factory :with_readonly_role, class: User do
    user_defaults

    after(:create) do |user, _|
      user.add_role :readonly
    end
  end
end