2017-06-21 15 views
1

後に失われるI持っている私は、私は簡単にコヒーレントデータを構築することができるように工場を設定しようとしていますファクトリー・ガールの建物とは、関連付けがビルド段階

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)にできるようにしたいと私は会社after_buildステージの最後でデバッグするときには、ユーザーアカウント上の例では

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_createステージの開始後、管理者プロファイルの関連ユーザーを失いました(コメントを参照)

何が問題なのですか? (:会社) 問題

会社= FactoryGirl.buildを参照するには

簡単な方法:ここでは参考のため

は、プロファイル/ユーザー

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 

EDITのために他の工場ですcompany.admins.first.user#=>存在します! company.save#=> true company.admins.first.user#=> Nil!

+0

@mudasobwaはちょうどFactoryGirlドキュメント に反対を読むん>作成呼び出しafter_buildとafter_createコールバックの両方を呼び出します。 https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#callbacks コードにブレークポイントを配置するときにこれを確認しました。おそらくこれはFGの古いバージョンのケースでしたが、今ではありません –

+0

本当に、私はFGの古いバージョンを指していました。これは無関係なので、上記のコメントは削除されます。 – mudasobwa

+0

それぞれのオブジェクトを明示的に再読み込みしようと思いますか? 'comp.reload.admins.first.reload.user'のように? – mudasobwa

答えて

0

企業モデルを保存すると、最初に2レベルの深いネストされたユーザーの関連付けが失われるようです。 SO代わり

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

関連する問題