Reputation: 958
I'm trying to use FactoryBot to create some test data. One of my factories is giving me trouble: it works fine when I instantiate with default values, but when I specify values for certain attributes, a different attribute comes out as nil
.
The model class indicates that one of the values is an enum, both have presence validators, and one value has has a unique key scoped to the other value. I have tried various options like using add_attribute
and sequence
in my factory definitions.
What am I missing? Is FactoryBot trying to treat this as an implicit association?
# app/models/course.rb
class Course < ApplicationRecord
validates :source, :source_id, presence: true
validates :source_id, uniqueness: {scope: :source, message: "duplicate id for specified source"}
enum source: {
test: 0,
sis: 1,
lms: 2,
cs: 3
}
end
# db/schema.rb
ActiveRecord::Schema[7.0].define(version: 2022_03_14_195055) do
create_table "courses", force: :cascade do |t|
t.integer "source"
t.string "source_id"
end
end
# test/factories.rb
FactoryBot.define do
factory :course do
source_id { "1234" }
source { "test" }
end
end
# test code
puts build(:course)
puts build(:course, source: "test").inspect
puts build(:course, source_id: "9999").inspect
puts build(:course, source: "test", source_id: "9999")
# Output
#<Course id: nil, source: "test", source_id: "1000" ... >
#<Course id: nil, source: "test", source_id: nil ... >
#<Course id: nil, source: nil, source_id: "9999" ... >
#<Course id: nil, source: nil, source_id: nil ... >```
Upvotes: 2
Views: 716
Reputation: 958
I just realized this is a known issue in FactoryBot. The solution seems to be something like:
factory :person do
name { "Daniel" }
transient do
thing_id { 0 }
thing { "thing" }
end
initialize_with do
new(attributes.merge(thing_id: thing_id, thing: thing))
end
end
Upvotes: 2