尝试使用FactoryGirl初始化数据时,我在访问以前创建的数据时遇到了问题。
假设我有 3 种不同的模型:产品、购物车项和订单项。这些是基本规则:
- 购物车项和订单项belong_to产品,并且是必需的。
- 产品具有唯一标识符"名称"。
我的工厂文件设置如下:
产品
FactoryGirl.define do
factory :product do
name "A Product"
end
end
购物车项
FactoryGirl.define do
factory :cart_item do
association :product do
Product.find_by(name: "A Product") || FactoryGirl.create(:product)
end
end
end
订单项
FactoryGirl.define do
factory :order_item do
association :product do
Product.find_by(name: "A Product") || FactoryGirl.create(:product)
end
end
end
现在,在一个测试中,我首先使用此调用FactoryGirl.create(:cart_item)
创建 CartItem
一切正常。由于没有产品,因此它会创建一个新产品,然后将其分配给购物车项。
接下来,我尝试使用此调用FactoryGirl.create(:order_item)
创建订单项
这次当我运行它时,它失败并显示错误Validation failed, Name has already been taken
尝试创建名为"产品"的新产品时,此操作失败,该产品已通过调用创建 CartItem 创建。
但是,这甚至不应该尝试创建新的产品实例,因为我使用此Product.find_by("A Product") || FactoryGirl.create(:product)
设置了 OrderItem 的产品,该应该首先尝试在创建新产品实例之前查找该产品实例。
关于为什么会发生这种情况的任何想法?
已更新
我相信您的问题在于您使用association
的方式。我没有看到任何地方的关联像你定义它的方式一样。
相反,你想做的是这样的
factory :cart_item do
product { Product.find_by(name: "A Product") || association(:product) }
end
这实际上似乎是错误的,因为你正在创建非确定性。相反,您应该创建一个记录,并在测试中将其直接分配给工厂。
FactoryGirl.define do
factory :cart_item do
association :product
end
end
FactoryGirl.define do
factory :order_item do
association :product
end
end
然后在您的测试中
product = FactoryGirl.create(:product)
cart_item = FactoryGirl.create(:cart_item, product: product)
order_item = FactoryGirl.create(:order_item, product: product)
这只是一个想法,但请尝试在 FactoryGirl 配置中注释掉 FactoryGirl.lint。