Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Senior Enums

Як змінювати перелік значень enum, коли дані вже в базі?

Enum у коді змінюється легко, а от рядки, які вже лежать у базі, - ні. Саме тут зʼявляються помилки після деплою.

Найнебезпечніше - перейменувати кейс:

// було
case Middle = 'middle';

// стало
case Mid = 'mid';

Код збереться, а всі наявні рядки зі значенням middle перестануть кастуватися: ValueError: "middle" is not a valid backing value. Впаде не міграція, а звичайна сторінка.

Правильний порядок для перейменування:

  1. Додати новий кейс, лишивши старий.
  2. Міграцією перевести дані: Vacancy::where('level', 'middle')->update(['level' => 'mid']).
  3. Наступним релізом прибрати старий кейс.

Додати новий кейс - безпечно, якщо колонка varchar. Але коли в базі використано нативний тип enum, потрібна ще й міграція самої колонки, а Schema::table()->change() для нативних enum працює не в усіх драйверах - подекуди доводиться писати DB::statement().

Тому колонку під enum майже завжди роблять string: перелік живе в PHP, база зберігає рядок, і зміни не потребують ALTER на великій таблиці.

Захист від падіння на невідомому значенні:

// null замість винятку, коли в базі щось несподіване
$level = VacancyLevel::tryFrom($vacancy->getRawOriginal('level'));

І ще одне: якщо enum використовується у валідації через Rule::enum(), видалений кейс одразу зробить старі збережені записи невалідними при редагуванні - про це згадують уже після скарг користувачів.

Докладніше в документації: Міграції

Схожі питання