2010-07-30 88 views
2

我有一個Person模型,它與Email模型有多對多的關係,我想創建一個工廠讓我爲該人生成姓名(這已經完成)並創建一個電子郵件地址這是基於該人的姓名。以下是我對創造一個person的名字:如何在factory_girl中構建/創建多對多關聯?

Factory.sequence :first_name do |n| 
    first_name = %w[FirstName1 FirstName2] # ... etc (I'm using a real subset of first names) 
    first_name[(rand * first_name.length)] 
end 

Factory.sequence :last_name do |n| 
    last_name = %w[LastName1 LastName2] # ... etc (I'm using a real subset of last names) 
    last_name[(rand * last_name.length)] 
end 

Factory.define :person do |p| 
    #p.id ??? 
    p.first_name { Factory.next(:first_name) } 
    p.last_name { Factory.next(:last_name) } 
    #ok here is where I'm stuck 
    #p.email_addresses {|p| Factory(:email_address_person_link) } 
end 

Factory.define :email_address_person_link do |eapl| 
    # how can I link this with :person and :email_address ? 
    # eapl.person_id ??? 
    # eapl.email_address_id ??? 
end 

Factory.define :email_address do |e| 
    #how can I pass p.first_name and p.last_name into here? 
    #e.id ??? 
    e.email first_name + "." + last_name + "@test.com" 
end 

回答

3

好吧,我想我明白你現在要問什麼。像這樣的東西應該工作(未經測試,但我已經做了在另一個項目類似的東西):

Factory.define :person do |f| 
    f.first_name 'John' 
    f.last_name 'Doe' 
end 

Factory.define :email do |f| 
end 

# This is optional for isolating association testing; if you want this 
# everywhere, add the +after_build+ block to the :person factory definition 
Factory.define :person_with_email, :parent => :person do |f| 
    f.after_build do |p| 
    p.emails << Factory(:email, :email => "#{p.first_name}.#{p.last_name}@gmail.com") 
    # OR 
    # Factory(:email, :person => p, :email => "#{p.first_name}.#{p.last_name}@gmail.com") 
    end 
end 

如前所述,使用第三,獨立的工廠是可選的。在我的情況下,我並不總是想爲每個測試生成關聯,所以我建立了一個單獨的工廠,我只在一些特定的測試中使用。

+0

這很有效,你搖滾!對於任何有興趣的人,請查看這個博客:http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl或http://railsondave.blogspot.com/2009/ 05 /創建-的hasMany-通工廠,with.html – DJTripleThreat 2010-08-08 01:42:48

2

使用回調(詳情參見FG文檔)。回調通過當前正在構建的模型。

Factory.define :person do |p| 
    p.first_name { Factory.next(:first_name) } 
    p.last_name { Factory.next(:last_name) } 
    p.after_build { |m| p.email_addresses << "#{m.first_name}.#{m.last_name}@test.com" } 
end 

我認爲這是有效的。

您還可以通過使用Faker gem來爲您節省一些工作,爲您創建真實的名字和姓氏以及電子郵件地址。

+0

我不認爲這是我正在尋找的東西。爲了清晰我編輯了我的問題。儘管如此,faker寶石+1。我想弄清楚如何做到這一點,所以我可以更好地瞭解factory_girl的工作原理。 – DJTripleThreat 2010-08-07 22:26:31

相關問題