我正在尝试使用FactoryGirl创建一个测试数据库,其关联是Parent has_many Entries。此时,它抛出了ActiveRecord验证错误,即Parent不能为空。我在这个问题上遇到了困难,并尝试了很多方法来创建这个关联的测试数据库。我认为我很接近,但我可能不会接近,可能会有基本的错误,所以非常感谢任何和所有的建议。
我猜是散列{parent_id :: id}没有被传递给Entry工厂。那将无法通过验证。但是,我不知道实际情况如此,即使是这样,我也不知道如何解决它。在此先感谢您的帮助...
错误是:
ActiveRecord :: RecordInvalid:验证失败:父级不能为空
RSpec呼叫是:
before(:all) do
rand(11..25).times { FactoryGirl.create(:parent) }
visit "/parents?direction=asc&sort=parent_blog"
end
after(:all) do
Parent.delete_all
end
父模型是:
class Parent < ActiveRecord::Base
has_many :entries, dependent: :destroy
accepts_nested_attributes_for :entries, :allow_destroy => :true
validates :parent_blog, presence: true,
uniqueness: true
end
Entry模型是:
class Entry < ActiveRecord::Base
belongs_to :parent
validates :entry_blog, presence:true,
uniqueness: true
validates :parent_id, presence: true
end
父工厂是:
FactoryGirl.define do
factory :parent do
sequence(:parent_blog) { |n| "http://www.parent%.3d.com/ss" % n }
entries { rand(5..15).times { FactoryGirl.create(:entry, parent_id: :id) } }
end
end
Entry工厂是:
FactoryGirl.define do
factory :entry do
sequence(:entry_blog) { |n| "http://www.parent%.3d.com/ss/entry%.3d" % [n, n] }
parent_id { :parent_id }
end
end
答案 0 :(得分:4)
以下对工厂定义的修改应该有效。我稍后会回来提供一些解释。
FactoryGirl.define do
factory :parent do
sequence(:parent_blog) { |n| "http://www.parent%.3d.com/ss" % n }
after(:create) {|parent| rand(5..15).times {FactoryGirl.create(:entry, parent: parent)}}
end
factory :entry do
sequence(:entry_blog) { |n| "http://www.parent%.3d.com/ss/entry%.3d" % [n, n] }
parent
end
end
这两项更改,在after
工厂中使用:parent
并使用parent
代替parent_id
,都是RSpec支持关联的示例,正如所讨论的那样在https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations。
至于为什么你的代码不起作用,我现在只能提供部分答案。您不能在初始父级创建中包含entries
的原因是,在创建父记录之前您没有父ID,但是由于{{{{}},您需要父ID来创建条目1}}验证Entry
的存在。换句话说,在您的父工厂评估parent_id
块时,parent_id
尚未设置。
我不确定为什么您无法在条目工厂中将entries
替换为parent
,并相应地将parent_id
替换为parent: parent
parent_id: parent.id
1}}在父工厂中调用。我在提交上述内容之前尝试了该变体,但失败了:
FactoryGirl.create
如果/我想出来的话,我会再次更新这个答案。