Нові виразні атрибути моделей у Laravel 13.2.0

Перекладено ШІ 2 Laravel News 02 червня, 2026

Laravel 13.2.0 приносить симетричні атрибути для Eloquent і пряму підтримку enum у #[Queue] та #[Connection]. Також з’явилися releaseOnSignal для withoutOverlapping, додаткові дані в UniqueConstraintViolationException і правильне відображення cron‑виразів у schedule:list.

Laravel 13.2.0 додає набір нових симетричних, виразних PHP-атрибутів для Eloquent-моделей, підтримку enum у #[Queue] та #[Connection], і не тільки.

Головні нововведення:

  • Нові симетричні атрибути для Eloquent-моделей (#[DateFormat], #[WithoutTimestamps] та ін.)
  • Підтримка enum у атрибутах черги #[Queue] і #[Connection]
  • Параметр releaseOnSignal для withoutOverlapping() — обробка раптового завершення процесу
  • UniqueConstraintViolationException тепер містить інформацію про колонки та індекс
  • schedule:list відображає cron-вирази в правильному часовому поясі

# Що нового

# Симетричні атрибути Eloquent-моделей

PR #59284 додає набір вузькоспрямованих, однозавданих атрибутів як альтернативу багатопараметровим атрибутам на кшталт #[Table]. Замість того, щоб поєднувати кілька налаштувань в одному атрибуті, кожне налаштування тепер має власний атрибут:

// Before
#[Table(timestamps: false, dateFormat: 'U')]
class Post extends Model {}
 
// After
#[DateFormat('U')]
#[WithoutTimestamps]
class Post extends Model {}

Нові атрибути відображають властивості, які вже є в Eloquent-моделях, що спрощує декларативну конфігурацію поведінки моделі на рівні класу.

Pull Request: #59284

# Підтримка enum у #[Queue] та #[Connection]

Атрибути PHP #[Queue] і #[Connection] тепер приймають backed enums безпосередньо, тож можна передавати case enum без виклику ->value:

// Before
#[Queue(Queues::LOGS_INGESTION->value)]
final class IngestAuditLog implements ShouldQueue {}
 
// After
#[Queue(Queues::LOGS_INGESTION)]
final class IngestAuditLog implements ShouldQueue {}

Це узгоджує поведінку атрибутів з тим, що вже підтримувалося через властивість безпосередньо.

Pull Request: #59278

# releaseOnSignal для withoutOverlapping()

withoutOverlapping() тепер приймає параметр releaseOnSignal. Якщо встановити його в true, замок перекриття (збережений як ключ кешу) звільняється при отриманні процесом сигналу завершення (SIGTERM, SIGINT або SIGQUIT), тож завдання може запуститися знову відразу після перезапуску планувальника.

Без цього, якщо процес планувальника вбити під час виконання завдання — що може трапитись на керованій інфраструктурі — замок лишиться встановленим і завдання не виконається знову, поки не сплине TTL замка.

Artisan::command('reports:generate', function () {
    // ...
})->withoutOverlapping(releaseOnSignal: true);

Потрібне розширення pcntl.

Pull Request: #59298

# UniqueConstraintViolationException містить дані про колонки та індекс

UniqueConstraintViolationException тепер відкриває доступ до колонок і назви індексу, що брали участь у порушенні унікальності. Наявність даних залежить від драйвера БД:

Driver columns index
SQLite
PostgreSQL
MySQL
SQL Server
try {
    User::create(['email' => 'taken@example.com']);
} catch (UniqueConstraintViolationException $e) {
    $e->columns; // e.g. ['email'] on PostgreSQL/SQLite
    $e->index;   // e.g. 'users_email_unique' on PostgreSQL/MySQL/SQL Server
}

Pull Request: #59299

# schedule:list відображає вирази в правильному часовому поясі

Команда schedule:list тепер показує cron-вирази, приведені до часового поясу, налаштованого для кожного завдання, замість того, щоб завжди відображати їх у часовому поясі додатка. Це робить вивід відповідним до реального часу виконання завдання.

Pull Request: #59286

# Атрибут Backoff тепер варіативний

Атрибут #[Backoff] тепер приймає варіативний перелік значень затримки, що відповідає підходу з масивом, доступному через властивість backoff у queued jobs:

#[Backoff(10, 30, 60)]
class ProcessOrder implements ShouldQueue {}

Pull Request: #59354

# Магічні factory-методи приймають кілька масивів

Динамічні factory-методи has*() (наприклад, hasPosts(), hasTags()) тепер приймають кілька масивів, тож можна передавати різні набори атрибутів для кожної пов’язаної моделі без ручного використання forEachSequence():

User::factory()
    ->hasPosts(['title' => 'First Post'], ['title' => 'Second Post'])
    ->create();

Внутрішньо передача кількох масивів викликає forEachSequence(), створюючи по одній пов’язаній моделі на кожен масив з відповідними атрибутами.

Pull Request: #59343

# Інші виправлення й покращення

Queue & Workers:

  • Додано причину зупинки worker — TimedOut (#59310)
  • Додана можливість відключити звітування про виключення job у worker (#59308)
  • Прив’язали слухача запитів для сторінки помилок, щоб запобігти росту використання пам’яті в Octane (#59309)

Models & Database:

  • Виправлено некоректне інкрементування атрибуту Table для Pivot-моделей (#59336)
  • Забезпечено роботу атрибута ScopedBy з наслідуванням (#59332)
  • Дозволено передавати enum в атрибути моделей (#59297)
  • Забезпечено роботу connectUsing() з UnitEnum (#59306)

Collections:

  • Колбек для sum() тепер отримує ключ елемента як другий аргумент (#59322)

HTTP & Streaming:

  • Обробка виключень у eventStream(), щоб уникнути фатальних помилок (#59292)
  • Виправлено сигнатуру LazyPromise::wait() для сумісності з PromiseInterface від Guzzle (#59301)

Testing:

  • Виправлено відсутню інверсію для асерта assertDontSeeInHtml() (#59303)

Error Page:

  • Додано підтримку mobile safe-area-inset у рендері виключень (#59341)

Performance:

  • Покращено продуктивність підстановки raw SQL-біндінгів (#59277)

# Посилання

Популярні

Інше, що варто прочитати