Factory Girl在Rails Association上跳过“before_add”回调

时间:2015-02-06 19:34:05

标签: ruby-on-rails factory-bot

我似乎无法让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,但不知何故实际上并没有#34;添加&#34;他们到集合中,所以我必须手动完成。

我是否错过了有关FactoryGirl应如何工作的信息?或者关于ActiveRecord如何运作?

1 个答案:

答案 0 :(得分:2)

这就是ActiveRecord的工作方式。

如果您在rails console中运行以下内容,则会看到该关联的before_add回调未被调用:

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

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

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

<强> 1。创建Lessoncourse

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

希望有所帮助。