2015-01-13 99 views
4

我是FactoryGirl的新手,並且遇到了此特定用例的問題,但似乎並未在文檔中介紹。FactoryGirl has_many與雙向存在驗證的關聯創建額外記錄

我有兩個模型,人和書。一個人有很多書,一本書屬於一個人,並且都有一個驗證,要求對方的存在。 (一本書必須有一個人,一個人必須至少有一本書。)

class Person < ActiveRecord::Base 
    has_many :books, inverse_of: :person 
    validates :books, presence: true 
end 

class Book < ActiveRecord::Base 
    belongs_to :person 
    validates :person, presence: true 
end 

我需要滿足他們的模型的最低驗證要求人與書的工廠。人工廠至少應創建一本書,書廠應創建一個人。

這裏是我的工廠:

FactoryGirl.define do 
    factory :person do 

    transient do 
     books_count 1 
    end 

    after :build do |person, evaluator| 
     person.books << FactoryGirl.build_list(:book, evaluator.books_count, person: person) 
    end 
    end 
end 

FactoryGirl.define do 
    factory :book do 
    association :person 
    end 
end 

此代碼爲FactoryGirl.create(:person)。然而,當我運行FactoryGirl.create(:book),會發生以下情況:

  1. 書記錄創建
  2. 創建了一個人的記錄
  3. 第二,不想要的書記錄被人工廠創建。

如果我更改Book工廠的人聯想到包括0 books_count,如association :person, books_count: 0,然後我得到的錯誤ActiveRecord::RecordInvalid: Validation failed: Books can't be blank,因爲ActiveRecord的認爲,新的個人紀錄至今無人書籍。

我希望書籍工廠創建一本書和一個人,並讓他們每個人都滿足彼此的要求。

如何更改此代碼,以便運行FactoryGirl.create(:book)將創建所需人員,然後在此停止?

+0

這怎麼可能?如果沒有先創建圖書,則無法創建人員,並且如果沒有首先創建人員,則無法創建圖書。這是一個循環依賴,AR會嚇壞了,「你不能直接調用create來保存父項」。即使你得到它的工作FG,我沒有得到現實生活用例 – Anthony

+0

啊,好吧。所以你說循環依賴是不合邏輯的,我沒有理由要這樣做?這將解釋爲什麼沒有關於此主題的文檔。 – django09

+0

爲了解釋我自己:我想讓兩者都需要彼此的原因是因爲看起來像沒有書一樣在數據庫中擁有一個人會浪費空間,就像浪費空間來擁有一個空間一樣在沒有人員的情況下預訂數據庫。沒有其他的都沒有用,所以我覺得他們應該互相要求。這個論點是否有效?還是我應該刪除一個人至少有一本書的要求? – django09

回答

1

總結@上的問題安東尼的評論:

這是不合邏輯的兩個對象,要求對方,因爲一個必須存在於其他存在之前。因此,有可能一個人需要的書:

class Person < ActiveRecord::Base 
    has_many :books, inverse_of: :person 
    validates :books, presence: true 
end 

或者一本書給需要的人:

class Book < ActiveRecord::Base 
    belongs_to :person 
    validates :person, presence: true 
end 

但兩者在一起是沒有意義的,因此並不受主動支持記錄。