Я пришел к этому такому вопросу, потому что я хотел иметь возможность предсказать идентификатор модели, созданной в моем наборе тестов (идентификатор был затем использован REST-запросом к внешней службе, и мне нужно было предсказать точное значение для макета запрос).
Я обнаружил, что Model.maximum(:id).next
, хотя и элегантно, не работает в среде тестирования рельсов с фиксациями транзакций, поскольку обычно в БД нет записей, поэтому он просто вернет nil
.
Транзакционные фиксаторы делают проблему еще более сложной, поскольку поле автоинкремента увеличивается, даже когда в БД нет записей. Кроме того, использование ALTER TABLE ***your_table_name*** AUTO_INCREMENT = 100
прерывает транзакцию, в которой находятся ваши тесты, поскольку для нее требуется собственная транзакция.
Я решил создать новый объект и добавить 1 к его идентификатору:
let!(:my_model_next_id) { FactoryBot.create(:my_model).id + 1 }
Хотя он несколько хакерский (и немного неэффективный для вашей БД, поскольку вы создаете дополнительный объект для его идентификатора), он не делает ничего глупого для транзакции и надежно работает в тестовой среде без записей (если только ваш тесты выполняются параллельно с доступом к одной и той же базе данных ... в этом случае: условия гонки ... может быть?).