我正在使用 Rails 2.2 项目来更新它。我正在用工厂替换现有的固定装置(使用 factory_girl)并且遇到了一些问题。问题在于表示具有查找数据的表的模型。当我使用具有相同产品类型的两种产品创建购物车时,每个创建的产品都在重新创建相同的产品类型。此错误来自对 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))]
添加的两个产品类型相同,创建每个产品时都会重新创建产品类型并创建副本。
生成的错误是:“ActiveRecord::RecordInvalid:验证失败:名称已被采用,代码已被采用”
解决方法
此示例的解决方法是覆盖正在使用的产品类型并传入特定实例,因此仅使用一个实例。“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
当我尝试使用相同产品类型的两个项目定义购物车时,我收到上述相同的错误。
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