Фабрика Bot HABTM ноль в таблице соединений - PullRequest
0 голосов
/ 14 января 2019

Я получаю (расстраивает!) Ошибку при запуске тестов rspec (с Factory Bot) для моего приложения на Rails. Я вижу следующую ошибку:

ActiveRecord::NotNullViolation:
        Mysql2::Error: Field 'group_id' doesn't have a default value: INSERT INTO `groups_users` VALUES ()

Это прерывисто - разные тесты будут выдавать ошибку на разных трассах - что может указывать на состояние гонки?

Мои модели настроены как:

User habtm Groups
Groups habtm Users

Сотрудники ДОЛЖНЫ принадлежать к одной группе - с подтверждением:

validates :groups, presence: { message: 'Staff must be in at least one group' }, if: :staff?

Пользователи

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

Группы

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

Общим фактором во всех неудачных тестах является фабрика создания пользователей (и создание групп, если пользователь ДОЛЖЕН принадлежать группе) - поэтому я сосредоточил свои усилия на этом.

Учитывая, что ошибка в таблице groups_users, я предполагаю, что она пытается сохранить запись в объединяемой таблице до того, как группа существует в таблице groups?

Основываясь на других сообщениях SO и тралении в Интернете, я пробовал различные способы настройки группы:

1) groups {|s| [s.association(:group)]}

2) after(:build) {|user| user.groups = [create(:group)]}

3) groups {[FactoryBot.create(:group)]}

Пользователи только что были созданы с помощью

let!(:staff_user) { FactoryBot.create(:a_staff_member) }

в отдельных спецификациях - так что ничего интересного там нет.

Однако, неважно, как я создаю группы на фабриках, это не имеет никакого значения - и у меня закончились идеи - любые указания или предложения будут с благодарностью приняты!

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Я думаю, что это может сработать, если вы так изменитесь.

 from
 after(:build) {|user| user.groups = [create(:group)]}

 to
 after(:create) {|user| user.groups = [create(:group)]}

После того, как идентификатор пользователя создан с помощью команды «create», тогда «users.groups» будет приемлемым.

0 голосов
/ 16 января 2019

удалось отследить проблему. После того, как на фабрике было создано несколько исчерпывающих отладочных сообщений о том, что группа была создана и назначена пользователю, стало ясно, что сообщение об ошибке, относящееся к нулевым значениям в таблице соединения между ними, на самом деле было красной сельдью и вызвано за пределами завода.

Я полагаю, что проблема была вызвана тем, что пользовательский сеанс / журнал не очищался между тестами Capybara.

Добавление:

config.after :each do
  Warden.test_reset!
end

до /spec/spec_helper.rb, похоже, решил проблему. Надеюсь, что волосы, вырванные во время этого расследования, отрастут!

0 голосов
/ 14 января 2019

Я думаю, что попытка изменить равенство с конкатенацией может сработать.

Я бы добавил after(:create) { |user| user.groups << create(:group) }

Переход к after(:create) - это главное здесь, так как проблема, с которой вы сталкиваетесь, также, похоже, пытается добавить запись таблицы присоединения для записи, которая еще не создана.

...