À l'aide de factory_girl dans les Rails avec des associations qui ont des contraintes. Prise en double erreurs

Je travaille avec des Rails 2.2 projet de travail pour le mettre à jour. Je suis pour remplacer les luminaires avec des usines (à l'aide de factory_girl) et ont eu quelques problèmes. Le problème, c'est avec des modèles qui représentent des tables avec des données de recherche. Lorsque je créer un Panier avec deux produits qui ont le même type de produit, chaque produit créé est de recréer le même type de produit. Cette erreur à partir d'un unique de validation sur le type de produit modèle.

Problème De Démonstration

C'est à partir d'une unité de test où j'ai créer un Panier et le mettre en pièces. J'ai dû le faire pour contourner le problème. Cela montre encore le problème. Je vais vous expliquer.

cart = Factory(:cart)
cart.cart_items = [Factory(:cart_item, 
                           :cart => cart, 
                           :product => Factory(:added_users_product)),
                   Factory(:cart_item, 
                           :cart => cart, 
                           :product => Factory(:added_profiles_product))]

Les deux produits étant ajoutés sont de même type et de même lors de chaque produit est créé, il est re-créer le type de produit et la création de doublons.

L'erreur, qui est généré est:
"ActiveRecord::RecordInvalid: la Validation a échoué: le Nom a déjà été prises, le Code a déjà été prises"

Solution de contournement

La solution de contournement pour cet exemple est de remplacer le type de produit utilisé et de la passer dans une instance spécifique de sorte qu'une seule instance. Le "add_product_type" est récupérée au début et transmise pour chaque panier d'un article.

cart = Factory(:cart)
prod_type = Factory(:add_product_type)   #New
cart.cart_items = [Factory(:cart_item,
                           :cart => cart,
                           :product => Factory(:added_users_product,
                                               :product_type => prod_type)), #New
                   Factory(:cart_item,
                           :cart => cart,
                           :product => Factory(:added_profiles_product,
                                               :product_type => prod_type))] #New

Question

Quelle est la meilleure façon d'utiliser factory_girl avec "pick-liste" types d'associations?

J'avais comme pour l'usine de définition pour tout contenir, au lieu d'avoir à monter dans le test, même si je peux vivre avec elle.

Arrière-plan et les Détails

usines/produit.rb

# Declare ProductTypes

Factory.define :product_type do |t|
  t.name "None"
  t.code "none"
end

Factory.define :sub_product_type, :parent => :product_type do |t|
  t.name "Subscription"
  t.code "sub"
end

Factory.define :add_product_type, :parent => :product_type do |t|
  t.name "Additions"
  t.code "add"
end

# Declare Products

Factory.define :product do |p|
  p.association :product_type, :factory => :add_product_type
  #...
end

Factory.define :added_profiles_product, :parent => :product do |p|
  p.association :product_type, :factory => :add_product_type
  #...
end

Factory.define :added_users_product, :parent => :product do |p|
  p.association :product_type, :factory => :add_product_type
  #...
end

Le but de ProductType du "code" est donc l'application peut donner une signification particulière pour eux. Le type de produit modèle ressemble à quelque chose comme ceci:

class ProductType < ActiveRecord::Base
  has_many :products

  validates_presence_of :name, :code
  validates_uniqueness_of :name, :code
  #...
end

usines/cart.rb

# Define Cart Items

Factory.define :cart_item do |i|
  i.association :cart
  i.association :product, :factory => :test_product
  i.quantity 1
end

Factory.define :cart_item_sub, :parent => :cart_item do |i|
  i.association :product, :factory => :year_sub_product
end

Factory.define :cart_item_add_profiles, :parent => :cart_item do |i|
  i.association :product, :factory => :add_profiles_product
end

# Define Carts

# Define a basic cart class. No cart_items as it creates dups with lookup types.
Factory.define :cart do |c|
  c.association :account, :factory => :trial_account
end

Factory.define :cart_with_two_different_items, :parent => :cart do |o|
  o.after_build do |cart|
    cart.cart_items = [Factory(:cart_item, 
                               :cart => cart, 
                               :product => Factory(:year_sub_product)),
                       Factory(:cart_item, 
                               :cart => cart, 
                               :product => Factory(:added_profiles_product))]
  end
end

Quand j'essaie de définir le panier avec deux éléments du même type de produit, je reçois le même message d'erreur décrit ci-dessus.

Factory.define :cart_with_two_add_items, :parent => :cart do |o|
  o.after_build do |cart|
    cart.cart_items = [Factory(:cart_item,
                               :cart => cart,
                               :product => Factory(:added_users_product)),
                       Factory(:cart_item,
                               :cart => cart,
                               :product => Factory(:added_profiles_product))]
  end
end
InformationsquelleAutor Mark Eric | 2010-01-06