How to change the class in FactoryBot traits

FactoryBot allows a :class option to its factory definitions, to set the class to construct. However, this option is not supported for traits.

Most often, you can just define a nested factory instead of a trait, and use the :class option there.

factory :message do
  factory :reply, class: Message::Reply do
    # ...
  end
end

If you need/want to use traits instead (for example, it might make more sense semantically), you can not use a :class on a trait.

In that case, use initialize_with to define the record's construction.

factory :message do
  trait :reply do
    initialize_with { Message::Reply.new(attributes) }
    # ...
  end
end

Now FactoryBot.build(:message, :reply) will construct a Message::Reply instead of a Message.

Arne Hartherz Over 6 years ago