2011-05-17 153 views
10

我有2個工廠。 Beta_user和Beta_invite。基本上,在Beta_user可以有效保存之前,我必須創建一個Beta_invite條目。不幸的是,這些模型沒有乾淨的關聯,但他們確實共享一個電子郵件字段。工廠女生依賴工廠

Factory.sequence :email do |n| 
    "email#{n}@factory.com" 
end 

#BetaInvite 
Factory.define :beta_invite do |f| 
    f.email {Factory.next(:email)} 
    f.approved false 
    f.source "web" 
end 

#User 
Factory.define :user do |f| 
    f.email {Factory.next(:email)} 
    f.password "password" 
end 


#User => BetaUser 
Factory.define :beta_user, :parent => :user do |f| 
    f.after_build do |user| 
    if BetaInvite.find_by_email(user.email).nil? 
     Factory(:beta_invite, :email => user.email) 
    end 
    end 
end 

因此,在beta beta_user工廠中,我嘗試使用after_build回調來創建beta_invite工廠。

然而,它似乎是行爲異步或什麼的。可能做了find_by_email取回?

如果我試試這個:

Factory(:beta_user) 
Factory(:beta_user) 
Factory(:beta_user) 

我得到一個失敗,說明沒有與用戶電子郵件beta_invite的記錄。

相反,如果我嘗試:

Factory.build(:beta_user).save 
Factory.build(:beta_user).save 
Factory.build(:beta_user).save 

我得到更好的結果。就好像調用.build方法並等待保存允許創建beta_invite工廠的時間一樣。而不是直接調用Factory.create。該文檔說,在調用Factory.create的情況下,after_build和after_create回調被調用。

任何幫助,非常感謝。

UPDATE:

所以我使用的用戶模型做了before_validation調用來檢查,如果有一個beta邀請的方法。如果我將此方法調用改爲before_save。它工作正常。有什麼我在看。 factory_girl何時運行after_buildafter_create回調與活動記錄的before_validationbefore_save有關?

+1

您可以發佈您的用戶類?這個錯誤可能在驗證中或者它們是如何設置的。你說他們沒有乾淨的協會也是奇怪的B/C。你究竟是什麼意思?顯示您的模型代碼將有所幫助。 – 2011-05-21 22:28:31

回答

11

對我來說,它似乎只是應該能夠工作,但我也有與工廠女孩協會的問題以及。我喜歡在這樣的情況下使用的一種方法,如果關係不那麼明顯,是定義一個特殊的方法,你的工廠內,如下所示:

def Factory.create_beta_user 
    beta_invite = Factory(:beta_invite) 
    beta_user = Factory(:user, :email => beta_invite.email) 
    beta_user 
end 

,並使用在測試中,只寫

Factory.create_beta_user 

希望這會有所幫助。

+0

這就是我所要做的 – corroded 2011-05-25 05:51:53

6

不知道這是否會幫助你,但是這是我使用的代碼:

# Create factories with Factory Girl 

FactoryGirl.define do 
    # Create a sequence of unique factory users 
    sequence(:email) { |n| "factoryusername+#{n}@example.com"} 

    factory :user do 
    email 
    password "factorypassword" 

    # Add factory user email to beta invite 
    after(:build) {|user| BetaInvite.create({:email => "#{user.email}"})} 
    end 
end 
+1

這個解決方案對FactoryGirl來說更具慣用性 – JStroop 2014-01-17 20:10:18