私はRails 2.2プロジェクトで作業しており、それを更新しています。既存のフィクスチャをファクトリ (factory_girl を使用) に置き換えていますが、いくつかの問題がありました。問題は、ルックアップ データを含むテーブルを表すモデルにあります。同じ商品タイプの 2 つの商品でカートを作成すると、作成された各商品が同じ商品タイプを再作成しています。これは、ProductType モデルの一意の検証によるエラーです。
問題のデモンストレーション
これは、カートを作成してバラバラにまとめた単体テストからのものです。問題を回避するためにこれを行う必要がありました。ただし、これはまだ問題を示しています。説明します。
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))]
追加される 2 つの製品は同じタイプであり、各製品が作成されると、製品タイプが再作成され、重複が作成されます。
生成されるエラーは次のとおりです。
回避策
この例の回避策は、使用されている製品タイプをオーバーライドし、特定のインスタンスを渡して、1 つのインスタンスのみが使用されるようにすることです。「add_product_type」は早い段階で取得され、各カート項目に渡されます。
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
質問
「選択リスト」タイプの関連付けで factory_girl を使用する最良の方法は何ですか?
テストでアセンブルするのではなく、ファクトリ定義にすべてを含めたいと思いますが、それでも問題ありません。
背景と詳細
工場/product.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
ProductType の「コード」の目的は、アプリケーションがそれらに特別な意味を与えることができるようにすることです。ProductType モデルは次のようになります。
class ProductType < ActiveRecord::Base
has_many :products
validates_presence_of :name, :code
validates_uniqueness_of :name, :code
#...
end
工場/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
同じ商品タイプの 2 つのアイテムでカートを定義しようとすると、上記と同じエラーが発生します。
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