Reputation: 667
Is it possible to define a default trait in FactoryGirl? If I define a factory like this (where both question_response belongs_to question):
factory :question_response do
question
work_history
trait :open do
question { FactoryGirl.create :question, question_type: 'open' }
end
end
When I do FactoryGirl.create :question_response, :open
it will first create a default question and then create another inside the trait, which is an unnecessary operation.
Ideally I'd like to do this:
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
And then doing FactoryGirl.create :question
will use the default trait, but it doesn't seem to be possible.
Upvotes: 10
Views: 4314
Reputation: 1751
Just in case someone else is looking for 'default trait' scenario, this was discussed with examples in https://github.com/thoughtbot/factory_bot/issues/528#issuecomment-18289143
Basically, you can define trait with defaults and then use it for different factories. And then you can use appropriate factory with needed configuration.
For example:
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
Upvotes: 1
Reputation: 10191
When I do FactoryGirl.create :question_response, :open it will first create a default question and then create another inside the trait
It's not true. if you specify the trait with question
, it will overwrite the factory behavior before creation so that it does not create a default question.
I checked it with FactoryGirl v4.5.0
Upvotes: 2
Reputation: 9742
Your trait is creating a 2nd record because you have a block that is creating a record:
trait :open do
question { FactoryGirl.create :question, question_type: 'open' }
end
Instead, you can do define a trait on question that has the question type set, and then have your question_response use that question with the open trait as its default.
factory.define :question do
trait :open do
question_type 'open'
end
end
factory.define :question_response do
association :question, :open
end
Upvotes: 0