代码之家  ›  专栏  ›  技术社区  ›  David Geismar

如何在after_build in factory bot rails中创建关联?

  •  0
  • David Geismar  · 技术社区  · 3 年前

    我有一个数据模型 account 在子域上具有唯一验证。

    我的大多数其他对象都与 账户 对象

    在我的数据模型中 product 有一个 account_id program_id

    在FactoryBot中,我想写一些类似的东西:

    create(:product, :with_program, account: account)
    

    然后创建与此特定帐户相关的所有资源。

    在我的 产品 工厂:

    FactoryBot.define do
      factory :product do
        association :account
        association :program
        trait :with_program do
          after_build do |product|
            product.program = create(
              :program,
              :with_author,
              account: product.account
            )
          end
        end
      end
    end
    

    然而,这直接创建了程序,该程序反过来重新创建了帐户,它们触发了帐户的唯一性验证。

    FactoryBot.define do
      factory :program do
        association :account
      end
    end
    

    到目前为止,我找到的唯一解决方案是在创建实际产品并将其传递给 create method :

      let(:program) do
          create(
            :program,
            :with_future_start_date_sessions,
            account: account,
            author: author
          )
        end
    create(
            :product,
            :draft,
            program: program,
            account: account
          )
        end
    

    有没有更聪明的方法来传递 账户 对所有人 产品 关联,并在 trait 或者类似的东西?

    0 回复  |  直到 3 年前
        1
  •  3
  •   R. Sierra    3 年前

    当创建复杂的关联时,我总是喜欢自上而下的方法。与其用帐户创建产品,不如尝试用产品创建帐户,这样您就不需要提前创建关联。

    FactoryBot.define do
      factory :account do
        # account attributes...
    
        trait :with_products do
          transient do
             product_count {2}
          end
    
          after(:build, :create) do |account, evaluator|
             create_list(
               :product,
               evaluator.product_count, 
               :with_program, 
               account: account
             )
          end
        end
      end
    end
    
    

    然后您可以通过调用

    # 1 account, 5 products
    FactoryBot::create(:account, :with_products, product_count: 5)
    # 5 accounts with 1 product each
    FactoryBot::create_list(:account, 5, :with_products, product_count: 1)