Factory Girl 建造并创建 3 个相关模型,建造阶段后关联丢失

Factory Girl building and creating 3 related models, association is lost after build stage

我有以下型号

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 阶段开始之后,我在管理员配置文件中丢失了关联用户(参见评论)

怎么了?

Profile/User

的其他工厂供参考
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 # => 真 company.admins.first.user#=>无!

似乎先保存公司模型会失去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