FactoryBot :association creates a second parent object

23 Views Asked by At

I have a rails 7.1 app.

A program can have many program_media and one of them is the main_program_media:

class Program < ApplicationRecord
  has_many :program_medias,
           inverse_of: :program, dependent: :destroy
          class_name: 'ProgramMedia',
          inverse_of: :program,
          dependent: :destroy

  has_one :main_program_media, -> { main },
          class_name: 'ProgramMedia',
          inverse_of: :program,
          dependent: :destroy
end 
class ProgramMedia < ApplicationRecord
  belongs_to :program, inverse_of: :program_medias
  scope :main, -> { where(main: true) }
end

I have a trait in my program factory so that a main program media is created:

FactoryBot.define do
  factory :program do
    trait :with_main_program_media do
      association :main_program_media, factory: %i[program_media main]
    end
  end 
end

However, we are seeing that the following line:

FactoryBot.create(:program, :with_main_program_media) 

creates not 1 but 2 programs. The program_media's program is a different one (not the one that invoked the factory).

I can fix it by changing the factory trait to:

trait :with_main_program_media do
  after(:build) do |program|
    program.main_program_media = build(:program_media, :main) # notice no need to manually assign the program which means associations are correctly set up
  end
end

but I think there's an underlying issue with how factory bot is working, because I would have expected the first to work in the same way as the second. What am I missing? The issue is the same with a has_one, and the fact that I'm using a scope in the association doesn't seem to change anything.

0

There are 0 best solutions below