Ruby on rails “工厂女孩跳过”;在“加上”之前;Rails上的回调关联

Ruby on rails “工厂女孩跳过”;在“加上”之前;Rails上的回调关联,ruby-on-rails,factory-bot,Ruby On Rails,Factory Bot,我似乎无法让FactoryGirl在添加带有关联模型的回调之前调用我的 我有一个课程模型: has_many :lessons, dependent: :destroy, before_add: :set_lesson_number def set_lesson_number #stuff end 包含以下内容的课程模型: 属于:课程 具有以下功能的课程工厂: FactoryGirl.define do factory :lesson do course end end

我似乎无法让FactoryGirl在添加带有关联模型的回调之前调用我的

我有一个课程模型:

has_many :lessons, dependent: :destroy, before_add: :set_lesson_number
def set_lesson_number
  #stuff
end
包含以下内容的课程模型:

属于:课程

具有以下功能的课程工厂:

FactoryGirl.define do
  factory :lesson do
    course
  end
end
以及课程工厂,定义如下:

当我执行
FactoryGirl.create(:lessue)
时,不会调用before\u add回调,但如果我执行以下操作,则会调用它:

lesson = FactoryGirl.build(:lesson)
course = lesson.course
course.lessons << l
是的。看起来FactoryGirl正在创建课程并设置课程ID,但实际上并没有将它们“添加”到集合中,所以我必须手动完成


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

这就是
ActiveRecord的工作原理

如果在
rails控制台中运行以下命令
,您将看到在未调用关联的_add
回调之前的

course = Course.create
Lesson.create(course_id: course.id)
我想象
FactoryGirl.create\u list
以类似的方式生成对象

需要将
课程
添加到集合中才能触发回调。这可以通过两种方式实现

1。通过
课程创建
课程

course.lessons.create
course.lessons << lesson
course.lessons = [lesson1, lesson2]
2。将
课程
明确添加到
课程。课程

course.lessons.create
course.lessons << lesson
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

希望这会有帮助。

乔丹,这肯定会有帮助。谢谢我很惊讶地发现
Lesson.course=course
也不能胜任这项工作。我一直认为这个集合只是一个抽象的事实,所有这些课程的
course\u id
都在数据库中设置为
course.id
,但这种行为使它看起来像是有意设计的(有些令人惊讶的)区别。您知道区分有用的原因吗?
lesson.course=course
不会添加到
lessons
集合中,因此不会触发回调。基本上,如果要启动回调,需要对集合进行操作。当想要绕过回调时,在关系的另一端创建记录可能很有用。