Factory Girl 跳过 "before_add" 对 Rails 协会的回调

Factory Girl skips "before_add" callback on Rails Association

我似乎无法让 FactoryGirl 使用关联模型调用我的 before_add 回调。

我有一个课程模型:

has_many :lessons, dependent: :destroy, before_add: :set_lesson_number
def set_lesson_number
  #stuff
end

一个课程模型:

belongs_to :course.

课程工厂:

FactoryGirl.define do
  factory :lesson do
    course
  end
end

和课程工厂,定义 as suggested by the Factory Girl wiki:

FactoryGirl.define do
  factory :course do
    factory :course_with_lessons do
      transient do
        lessons_count 10
      end

      after(:create) do |course, evaluator|
        create_list(:lesson, evaluator.lessons_count, course: course)
      end
    end
  end
end 

当我执行 FactoryGirl.create(:lesson) 时,before_add 回调不会被调用,但如果我这样做,它会被调用:

lesson = FactoryGirl.build(:lesson)
course = lesson.course
course.lessons << l

在这两种情况下,course.lessons 最终包括课程。

出于同样的原因,FactoryGirl.build(:course_with_lessons) 不适用于上述课程工厂,但如果我将 create_list 行替换为:

evaluator.lessons_count.times do
  course.lessons << build(lesson)
end

确实如此。好像 FactoryGirl 正在创建课程并设置他们的课程 ID,但不知何故实际上 "adding" 它们并没有添加到集合中,所以我必须手动完成。

我是否遗漏了有关 FactoryGirl 应该如何工作的信息?或者关于 ActiveRecord 的工作原理?

这就是 ActiveRecord 的工作方式。

如果您 运行 在您的 rails console 中执行以下操作,您将看到 before_add 关联上的回调未被调用:

course = Course.create
Lesson.create(course_id: course.id)

我想 FactoryGirl.create_list 以类似的方式生成对象。

需要将 lesson 添加到集合中才能触发回调。这可以通过几种方式完成。

1.通过 course

创建一个 Lesson
course.lessons.create

2。将 lesson 显式添加到 course.lessons

course.lessons << lesson

3。显式添加lesson的集合到course.lessons

course.lessons = [lesson1, lesson2]

要触发回调,您可以像这样修改您的工厂:

  factory :course do
    factory :course_with_lessons do
      transient do
        lessons_count 10
      end

      after(:create) do |course, evaluator|
        course.lessons = 
          build_list(:lesson, evaluator.lessons_count, course: course)
        course.save
      end
    end
  end

希望对您有所帮助。