如何在factory_girl中创建一个对象,该对象验证它至少有一个关联对象?

时间:2014-06-06 11:56:43

标签: ruby-on-rails ruby factory-bot

有以下代码:

  let!(:beauty_salon_service) { create(:beauty_salon_service) }
  let!(:beauty_salon_employee) { build(:beauty_salon_employee, 
                                       business: beauty_salon_service.beauty_salon_category.business) }
  before do
    beauty_salon_employee.beauty_salon_employee_services.build(beauty_salon_service: beauty_salon_service)
    beauty_salon_employee.save!
  end

两个条件:

  1. beauty_salon_service和beauty_salon_employee必须指向 相同的业务(你可以看到);
  2. beauty_salon_employee一定没有     空白has_many通过关联beauty_salon_employee_services     (验证存在);
  3. 我的FactoryGirl代码不起作用 - “验证失败:美容院员工服务不能为空”。我该如何解决?提前致谢。

1 个答案:

答案 0 :(得分:1)

let!发生在before之前,因此创建的员工没有服务(您可能知道)。要解决您的紧急问题,您需要在创建员工时提供服务。

您可以在factory_girl(或ActiveRecord中)创建对象时初始化多对多关系,如下所示:

let!(:beauty_salon_employee) do
  build :beauty_salon_employee,
    business: beauty_salon_service.beauty_salon_category.business,
    beauty_salon_employee_services: [beauty_salon_service]
end

虽然你真正想做的是在BeautySalonFactory中创建BeautySalonService。 The factory_girl documentation for associations给出了如何在回调中填充一对多关联的示例:

FactoryGirl.define do

  # post factory with a `belongs_to` association for the user
  factory :post do
    title "Through the Looking Glass"
    user
  end

  # user factory without associated posts
  factory :user do
    name "John Doe"

    # user_with_posts will create post data after the user has been created
    factory :user_with_posts do
      # posts_count is declared as a transient attribute and available in
      # attributes on the factory, as well as the callback via the evaluator
      ignore do
        posts_count 5
      end

      # the after(:create) yields two values; the user instance itself and the
      # evaluator, which stores all values from the factory, including transient
      # attributes; `create_list`'s second argument is the number of records
      # to create and we make sure the user is associated properly to the post
      after(:create) do |user, evaluator|
        create_list(:post, evaluator.posts_count, user: user)
      end
    end
  end
end

在您的情况下,您需要使用before_create而不是after_create来满足您的验证。