Enum у коді змінюється легко, а от рядки, які вже лежать у базі, - ні. Саме тут зʼявляються помилки після деплою.
Найнебезпечніше - перейменувати кейс:
// було
case Middle = 'middle';
// стало
case Mid = 'mid';
Код збереться, а всі наявні рядки зі значенням middle перестануть кастуватися: ValueError: "middle" is not a valid backing value. Впаде не міграція, а звичайна сторінка.
Правильний порядок для перейменування:
- Додати новий кейс, лишивши старий.
- Міграцією перевести дані:
Vacancy::where('level', 'middle')->update(['level' => 'mid']). - Наступним релізом прибрати старий кейс.
Додати новий кейс - безпечно, якщо колонка varchar. Але коли в базі використано нативний тип enum, потрібна ще й міграція самої колонки, а Schema::table()->change() для нативних enum працює не в усіх драйверах - подекуди доводиться писати DB::statement().
Тому колонку під enum майже завжди роблять string: перелік живе в PHP, база зберігає рядок, і зміни не потребують ALTER на великій таблиці.
Захист від падіння на невідомому значенні:
// null замість винятку, коли в базі щось несподіване
$level = VacancyLevel::tryFrom($vacancy->getRawOriginal('level'));
І ще одне: якщо enum використовується у валідації через Rule::enum(), видалений кейс одразу зробить старі збережені записи невалідними при редагуванні - про це згадують уже після скарг користувачів.