基于当前工厂的FactoryGirl从属对象

时间:2012-10-18 18:40:29

标签: ruby-on-rails factory-bot

我有鸡和蛋类型的问题。我有一个具有default_domain _id的Isp模型,我需要为我的测试填充。问题是域属于ISP。所以我想弄清楚如何构建工厂来生成ISP

工厂/ isp.rb

FactoryGirl.define do
  factory :isp do
    sequence :name do |n|
      "ISP" + n.to_s
    end
  end
end

工厂/ domain.rb

FactoryGirl.define do
  factory :domain do
    isp
    account
    sequence :dn do |n|
      "foo-#{n}.com"
    end
    active :true
  end
end

应用程序/模型/ isp.rb

class Isp < ActiveRecord::Base
  has_many :domains
  belongs_to :default_domain, class_name: 'Domain'
 end

应用程序/模型/ domain.rb

class Domain < ActiveRecord::Base
  belongs_to :isp
  ...
 end

我尝试在工厂中使用after(:create)回调,这似乎只是创建循环引用。尝试使用块来懒惰地评估它。一样。只是不知道在哪里看下一个或我应该尝试..

2 个答案:

答案 0 :(得分:1)

所以当然在这里张贴它让我立刻得到了解决我做错的事情。

发现此博文的提示#4

http://randomsoftwareinklings.blogspot.com/2012/03/factory-girl-automatic-tests.html

导致我

 FactoryGirl.define do
  factory :isp do
    sequence :name do |n|
      "ISP" + n.to_s
    end
    default_domain {Domain.find_or_create_by_dn("#{name}.com") }
  end
end

现在按预期工作。

答案 1 :(得分:0)

看来你找到了解决方案。但是,如果要使用工厂创建default_domain属性,请尝试此操作。

首先,如果您更改了domain工厂,使其无法引用isp工厂,那么您将避免使用循环引用。

其次,在isp工厂定义中,您可以执行此操作:

FactoryGirl.define do
  factory :isp do
    sequence(:name) {|n| "ISP#{n}" }
    after_create do |isp|
      isp.default_domain = Domain.find_by_dn("#{isp.name}.com") ||
        FactoryGirl.create(:domain, :dn => "#{isp.name}.com")
      isp.save!
    end
  end

这将允许您使用FactoryGirl获取Domain模型的更复杂属性,如果您想从工厂外部自定义dn字段,您可以使用瞬态属性并在after_create挂钩。