2010-01-13 93 views
6

我有一个问题,我有一个父母模型Foo,这两个has_many :barshas_many :bazes。最后,我还有一个加入模型BarBaz其中belongs_to :barbelongs_to :baz。我想验证所有bar_bazes,以便它的bar和baz都属于同一个foo。但我似乎无法找到一种方法来为这个模型定义一个有效的工厂。factory_girl关联验证

Factory.define(:bar) do |bar| 
    bar.association(:foo) 
end 

Factory.define(:baz) do |baz| 
    bar.association(:foo) 
end 

Factory.define(:bar_baz) do |bar_baz| 
    baz_bar.association(:foo) 
    baz_bar.association(:bar) 
    baz_bar.association(:baz) 
end 

我得到一个无效的记录错误,当我尝试创建后者,因为酒吧和巴兹factory_girl尝试关联它每个人都有自己富。我拧了吗?

回答

5

因此,经过几个小时的打击我的头反对这个问题,我想我终于有一个解决方案。虽然这很疯狂,所以希望其他人仍然可以告诉我我愚蠢的地方。

Factory.define :foo do |foo| 
end 

Factory.define :bar do |bar| 
end 

Factory.define :baz do |baz| 
end 

Factory.define :foo_with_baz do |foo| 
    foo.after_create { |foo| Factory(:baz, :foo => foo) } 
end 

Factory.define :bar_baz do |bar_baz| 
    bar_baz.bar {|bar| bar.association(:bar, :foo => Factory(:foo_with_baz)) 
    bar_baz.after_build {| bar_baz| bar_baz.baz_id = bar_baz.foo.bars.first.id } 
end 

的关键问题是,有需要在数据库中的FOO已经可以在通过工厂独自一人的,因为你可以在factories.rb使用局部变量或任意Ruby代码(据我可以告诉)。

+0

这是非常令人印象深刻的工作。伟大的工作 – Trip 2010-09-20 23:55:08

+0

好吧,它不可能那么伟大,因为在几个月后回到它之后,我不记得我到底在做什么。 :) – tfwright 2010-09-21 17:19:34

0

创建深度嵌套关联的工厂的疯狂使我创建了fixie,它允许您使用ActiveRecord创建测试记录。它在db:test:prepare步骤中运行。我用它来消除对灯具的需求。您可以继续使用工厂来生成更容易构建的对象。

+0

我真的很喜欢这一点,但为什么我们不能让我们的工厂解决方案允许在工厂定义中的任意Ruby代码? – tfwright 2010-01-15 05:00:39

+0

你可以在一定程度上。你需要解决的技巧是多次调用工厂,并且每次都需要生成一个有效的对象。这与协会混乱。 – 2010-01-15 21:40:03