I am getting a (frustrating!) error when running rspec (with Factory Bot) tests for my Rails app. I'm seeing the following error:
ActiveRecord::NotNullViolation:
Mysql2::Error: Field 'group_id' doesn't have a default value: INSERT INTO `groups_users` VALUES ()
It is intermittent - different tests will throw the error on different runs - which might suggest a race condition?
My models are configured as:
User habtm Groups
Groups habtm Users
Staff members MUST belong to one group - with a validation of:
validates :groups, presence: { message: 'Staff must be in at least one group' }, if: :staff?
Users
factory :a_staff_member, class: User do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
username { "#{first_name}_#{last_name}".downcase.gsub(/[^a-z]/i, '') }
email { "#{first_name}.#{last_name}@example.ac.uk".downcase }
user_type { :staff }
groups {|s| [s.association(:group)]}
end
Groups
FactoryBot.define do
factory :group do
sequence(:title) { |n| "Group Number #{n}" }
sequence(:short_title) { |n| "GRP#{n}" }
sequence(:url_slug) { |n| "grp#{n}" }
end
end
The common factor in all of the failing tests is the User creation factory (and the Groups creation given a User MUST belong to a group) - so this is where I have been focussing my efforts.
Given that the error is on the groups_users table I'm guessing that it's trying to save an entry to the join table before the group exists in the groups table?
Based on other SO posts and trawling the Internet, I've tried various ways of setting the group:
1) groups {|s| [s.association(:group)]}
2) after(:build) {|user| user.groups = [create(:group)]}
3) groups {[FactoryBot.create(:group)]}
The users are just instantiated via
let!(:staff_user) { FactoryBot.create(:a_staff_member) }
in the individual specs - so nothing exciting there.
However, no mater how I create the groups in the factories it doesn't make any difference - and I've run out of ideas - any pointers or suggestions would be gratefully received!