2017-06-21 41 views
1

後丟了,我有以下型號工廠女孩建設和創建3個相關的模型,協會正在構建階段

class Company 
    has_many :admins, class_name: 'Profile::CompanyAdmin' 

    validates :must_have_at_least_one_admin_validation 

    def must_have_at_least_one_admin_validation 
    errors.add(:admins, :not_enough) if admins.size.zero? 
    end 
end 

class Profile::CompanyAdmin 
    belongs_to :company 
    belongs_to :user, inverse_of: :company_admin_profiles 
end 

class User 
    has_many :company_admin_profiles, inverse_of: :user 
end 

我想辦廠,所以我可以輕鬆地構建一致的數據。特別是,我希望能夠create(:company, *traits),它創建了一個用戶帳戶

factory :company do 

    transient do 
    # need one admin to pass validation 
    admins_count 1   # Admins with a user account 
    invited_admins_count 0 # Admins without user account 
    end 

    after(:build) do |comp, evaluator| 
    # Creating a company admin with a user 
    comp.admins += build_list(:company_admin_user, 
     evaluator.admins_count, 
     company: comp 
    ).map { |u| u.company_admin_profiles.first } 
    comp.admins += build_list(:company_admin_profile, 
     evaluator.invited_admins_count, 
     company: comp 
    ) 
    comp.entities = build_list(:entity, 
     evaluator.entity_count, 
     company: comp 
    ) 
    # If I debug here, I have 
    # comp.admins.first.user # => Exists ! 

    end 

    after(:create) do |comp, evaluator| 
    # If I debug here 
    # comp.admins.first.user # => Gone 

    # First save users of admin profiles (we need the user ID for the admin profile user foreign key) 
    comp.admins.map(&:user).each(&:save!) 
    # Then save admins themselves 
    comp.admins.each(&:save!) 
    end 

在上面的例子中的管理員配置文件,當我在公司after_build階段結束調試,我已經成功地構建管理型材他們的用戶,但是在after_create階段開始後,我在管理員配置文件中丟失了相關用戶(參見注釋)

出現了什麼問題?

對於這裏的基準是其他工廠進行資料/用戶

factory(:company_admin_user) do 

    transient do 
    company { build(:company, admins_count: 0) } 
    end 

    after(:build) do |user, evaluator| 
    user.company_admin_profiles << build(:company_admin_profile, 
     company: evaluator.company, 
     user: user, 
    ) 
    end 

    after(:create) do |user, evaluator| 
    user.rh_profiles.each(&:save!) 
    end 

end 

factory :company_admin_profile, class: Profile::CompanyAdmin do 
    company 
    user nil # By default creating a CompanyAdmin profile does not create associated user 
end 

編輯:

更簡單的方法,看問題

公司= FactoryGirl.build(:公司) company.admins.first.user#=>存在! company.save#=> true company.admins.first.user#=>無!

+0

@mudasobwa只讀過FactoryGirl文檔 在對面>調用創建將調用都after_build和after_create回調。 https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#callbacks 我在代碼中放置斷點時證實了這一點。也許這是在舊版FG中的情況,但現在不是 –

+0

呃,實際上,我指的是FG的過時版本。將刪除上面的評論,因爲它是無關緊要的。 – mudasobwa

+0

你介意嘗試明確地_reload_各自的對象嗎?像'comp.reload.admins.first.reload.user'? – mudasobwa

回答

0

看起來公司模型首先失去了2級深層嵌套的用戶關聯。因此,而不是

after(:create) do |comp, evaluator| 
    # First save the users 
    comp.admins.map(&:user).compact.each(&:save!) 

    # Then save admins themselves 
    comp.admins.each(&:save!) 

下不工作(仍然不明白爲什麼雖然)

before(:create) do |comp, evaluator| 
    # Need to save newly created 2-level deep nested users first 
    comp.admins.map(&:user).compact.each(&:save!) 
end 

after(:create) do |comp, evaluator| 
    # Then save admins themselves 
    comp.admins.each(&:save!) 
end 
+0

這顯然有效,但是嵌套模型應該在正確配置時保存在父級中。 – mudasobwa