2012-05-02 53 views
18

在Rails應用程序驗證一個的has_many創建相關聯的列表,給出三種型號的用戶,文章和審閱與下面的關係和驗證:怎麼樣的工廠女孩​​與需要它的創建

class User < ActiveRecord::Base 
    has_many :articles 
    has_many :reviewers 
end 

class Reviewer < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :article 
end 

class Article < ActiveRecord::Base 
    belongs_to :user 
    has_many :reviewers 

    validate :has_reviewers? 

    def has_reviewers? 
    errors.add(:base, "article must have at least one reviewer.") if self.reviewers.blank? 
    end 
end 

並使用較新的DSL以下工廠:

FactoryGirl.define do 

    factory :user do 
    name { (8...20).map{ ('a'..'z').to_a[rand(26)] }.join } 
    age { Kernel.rand(100) } 
    end 

    factory :article do 
    body "This is the article content" 
    title "This is the title" 
    user 
    after_create do |article| 
     article.reviewers = create_list(:user, 2) 
    end 
    end 

    factory :reviewer do 
    user 
    article 
    state { ["published","draft","rejected","archived"][Kernel.rand(4)] } 
    end 

end 

的工廠,因爲驗證失敗以創建該項目不起作用評審創建之前:

> FactoryGirl.create(:article) 
ActiveRecord::RecordInvalid: Validation failed: article must have at least one reviewer. 

我已經做了比我想承認試圖克服這個障礙更多的嘗試,但我被卡住了!我有一個想法是創建這樣的審稿人:

factory :article do 
    body "This is the article content" 
    title "This is the title" 
    user 
    reviewers {|a| [FactoryGirl.create(:reviewer, article: a)] } 
    end 

但在這種情況下,「a」不是實例。所以這也行不通,就像以前一樣。

回答

3
factory :article do 
    reviewers {|a| [a.association(:reviewer)] } 
end 

factory :article do 
    before_create do |a| 
    FactoryGirl.create(:reviewer, article: a) 
    end 
end 
+0

當我嘗試,我得到:SystemStackError:堆棧層次過深。這似乎是審稿人工廠被解僱時,它不知道文章,所以它試圖創建另一篇文章。 – Blizzo

+0

@Blizzo您可以從審閱者工廠刪除文章創建或使用before_create。我編輯了我的答案以反映這一點。 – Unixmonkey

+0

我給了你的第二個例子一個鏡頭,以及你添加它後,並得到驗證錯誤:ActiveRecord :: RecordInvalid:驗證失敗:文章必須至少有一個審閱者 – Blizzo

22

我轉貼這個在工廠女孩GitHub的頁面上的問題,周圍的工作我的方式回答:

before_create do |article| 
    article.reviewers << FactoryGirl.build(:reviewer, article: article) 
end 

的關鍵是這樣做的一個before_create,所以驗證還沒有開始,並確保將新創建的審閱者推送到正在創建的實例上的評論列表中。由於Unixmonkey應對和讓我嘗試新事物:)

https://github.com/thoughtbot/factory_girl/issues/369#issuecomment-5490908

+0

我有一個類似的問題,這解決了它。謝謝! – ryanpitts1

1

新的語法是:

before(:create) do |article| 
    article.reviewers << FactoryGirl.build(:reviewer, article: article) 
end