Is there some configuration in a factory of factory girl/machinist that forces it to create objects with the same factory name just once during test case and return the same instance all the time? I know, i can do something like:
def singleton name
@@singletons ||= {}
@@singletons[name] ||= Factory name
end
...
Factory.define :my_model do |m|
m.singleton_model { singleton :singleton_model }
end
but maybe there is a better way.
You can use the initialize_with
macro inside your factory and check to see if the object already exists, then don't create it over again. This also works when said factory is referenced by associations:
FactoryGirl.define do
factory :league, :aliases => [:euro_cup] do
id 1
name "European Championship"
owner "UEFA"
initialize_with { League.find_or_create_by_id(id)}
end
end
There is a similar question here with more alternatives: Using factory_girl in Rails with associations that have unique constraints. Getting duplicate errors
@CubaLibre answer with version 5 of FactoryBot:
FactoryGirl.define do
factory :league do
initialize_with { League.find_or_initialize_by(id: id) }
sequence(:id)
name "European Championship"
end
end
Not sure if this could be useful to you.
With this setup you can create n products using the factory 'singleton_product'. All those products will have same platform (i.e. platform 'FooBar').
factory :platform do
name 'Test Platform'
end
factory :product do
name 'Test Product'
platform
trait :singleton do
platform{
search = Platform.find_by_name('FooBar')
if search.blank?
FactoryGirl.create(:platform, :name => 'FooBar')
else
search
end
}
end
factory :singleton_product, :traits => [:singleton]
end
You can still use the standard product factory 'product' to create a product with platform 'Test Platform', but it will fail when you call it to create the 2nd product (if platform name is set to be unique).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With