2010-11-30 9 views
11

Y a-t-il une configuration dans une usine d'usine fille/machiniste qui l'oblige à créer des objets avec le même nom d'usine une seule fois pendant le test et retourner la même instance tout le temps? Je sais, je peux faire quelque chose comme:Les usines Singleton dans factory_girl/machiniste?

def singleton name 
    @@singletons ||= {} 
    @@singletons[name] ||= Factory name 
end 
... 
Factory.define :my_model do |m| 
    m.singleton_model { singleton :singleton_model } 
end 

mais peut-être qu'il y a un meilleur moyen.

Répondre

1

Vous ne savez pas si cela peut vous être utile.

Avec cette configuration, vous pouvez créer n produits en utilisant l'usine 'singleton_product'. Tous ces produits auront la même plate-forme (c'est-à-dire la plate-forme '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 

Vous pouvez toujours utiliser l'usine de produits standard « produit » pour créer un produit avec la plate-forme « Test Platform », mais il échouera lorsque vous appelez pour créer le 2ème produit (si le nom de la plate-forme est définie comme unique).

+0

réponse plus détaillée dans ce sujet, y compris une explication plus approfondie de ce qui précède, plus un solution de rechange si vous utilisez le concombre: http://stackoverflow.com/questions/2015473/using-factory-girl-in-rails-with-associations-that-unve-unique-constraints-gett/8343150#8343150 –

17

Vous pouvez utiliser la macro initialize_with dans votre usine et vérifier si l'objet existe déjà, puis ne pas le créer à nouveau. Cela fonctionne également lorsque l'usine est référencée par des 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 

Il y a une question similaire ici avec d'autres alternatives: Using factory_girl in Rails with associations that have unique constraints. Getting duplicate errors

+2

Avec Rails 4, vous aurez besoin d'utiliser League.where (: id => id) .first_or_create - Si vous avez un before_save qui nécessite des informations à définir, alors vous pouvez vouloir find_or_initialize_by_id ou first_or_ini tialiser –