FactoryGirl关联父母不能为空

时间:2013-08-17 20:20:42

标签: activerecord rspec factory-bot

我正在尝试使用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

1 个答案:

答案 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

如果/我想出来的话,我会再次更新这个答案。