У Laravel 12.54.0 з’явився Model::withoutRelation() — метод для вибіркового видалення зв’язків із клонованої моделі

0
Перекладено ШІ
Оригінал: Laravel News
Оновлено: 12 березня, 2026
Laravel v12.54.0 додає Model::withoutRelation() для клонування моделей без конкретних відносин, метод interval() для зручного парсингу тривалостей і композитний індекс для покращення продуктивності черг. Хочете дізнатися, як ці зміни спростять роботу з моделями, запитами й тестами — читайте статтю.

Laravel v12.54.0 додає Model::withoutRelation() для вибіркового видалення зв’язків у клонованому екземплярі моделі, вводить interval() в InteractsWithData для парсингу значень тривалості та додає композитний індекс у таблицю jobs для прискорення опитування черги.

Основні нововведення:

Що нового

Model::withoutRelation()

Model::withoutRelation() створює клон моделі з видаленими вказаними зв’язками, не змінюючи оригінал. Це проміжний варіант між withoutRelations() — яке прибирає всі зв’язки — та unsetRelation(), яке мутує модель на місці.

// Remove a single relation from a clone
$lightweight = $post->withoutRelation('comments');
 
// Remove multiple relations
$lightweight = $post->withoutRelation(['comments', 'tags']);
 
// Original is untouched
$post->relationLoaded('comments'); // true

Зручно для уникнення циклічних посилань, зменшення розміру payload у queued jobs та підготовки моделей до серіалізації, не видаляючи всі eager-loaded дані.

Pull Request: #59137

interval() у InteractsWithData

Новий метод interval() у InteractsWithData перетворює вхідні значення запиту в екземпляр CarbonInterval. Він приймає рядки ISO 8601, або числові значення з вказаною одиницею.

// ISO 8601 duration string ("P1DT2H" → 1 day, 2 hours)
$request->interval('duration');
 
// Numeric value with a string unit
$request->interval('timeout', 'second');  // "90" → 90 seconds
$request->interval('cooldown', 'day');    // "7"  → 7 days
 
// Or using the Carbon\Unit enum
$request->interval('delay', Unit::Minute);

Тепер, поряд із date(), форми мають нативний спосіб працювати з полями тривалості.

Pull Request: #59114

Контекст запиту у Response::dump()

Response::dump() HTTP-клієнта тепер показує метод запиту, URL і код статусу разом з тілом відповіді. Раніше виводилося лише тіло, що ускладнювало ідентифікацію відповіді при ланцюжку запитів.

// Before
{"error": {"message": "Invalid card"}}
 
// After
"POST https://api.stripe.com/v1/charges" 422
{"error": {"message": "Invalid card"}}

Pull Request: #59136

Підтримка BinaryFileResponse в асертах

Тестові відповіді від response()->file() і response()->download() тепер підтримують асерти на стрімінг контенту. Раніше assertStreamedContent() на BinaryFileResponse падало, бо тестовий response не міг прочитати файл.

$this->get('/download/report.pdf')
    ->assertOk()
    ->assertStreamedContent(file_get_contents('report.pdf'));

Pull Request: #59018

queue:monitor показує найстарішу очікувану задачу

Команда queue:monitor тепер виводить в стандартний текстовий потік вік найстарішої pending job. Раніше ця інформація була доступна лише в JSON-виводі.

Pending jobs ...................................... 3
Delayed jobs ...................................... 0
Reserved jobs ..................................... 1
Oldest pending job ................................ 2 minutes ago

Pull Request: #59073

Користувацькі розширення Markdown для Mail

Рендеринг Markdown у mail тепер дозволяє додавати власні CommonMark-розширення через конфіг mail.markdown.extensions. Раніше завантажувалися лише Core і Table extensions.

// config/mail.php
'markdown' => [
    'extensions' => [
        League\CommonMark\Extension\Strikethrough\StrikethroughExtension::class,
        League\CommonMark\Extension\TaskList\TaskListExtension::class,
    ],
],

Тут можна реєструвати будь-яке розширення, що реалізує CommonMark ExtensionInterface.

Pull Request: #59051

Композитний індекс у таблиці jobs

Міграція таблиці jobs тепер створює композитний індекс на (queue, reserved_at, available_at) замість індексу лише на queue. На навантажених чергах попередній одно-колонковий індекс змушував БД сканувати рядки, фільтруючи по reserved_at та available_at під час кожного опитування. Новий індекс відповідає формі запиту для опитування черги.

Це нова міграція й діє лише для чистих інсталяцій або додатків, що повторно запускають міграції. Існуючим проєктам слід додати індекс вручну за потреби.

Pull Request: #59111

Тип колонки tsvector для PostgreSQL

Schema builder тепер підтримує тип колонки tsvector для PostgreSQL, тож більше не потрібно використовувати raw SQL при визначенні колонок для повнотекстового пошуку.

Schema::table('articles', function (Blueprint $table) {
    $table->tsvector('search_vector')->nullable()->storedAs(
        "setweight(to_tsvector('english', coalesce(title, '')), 'A') || " .
        "setweight(to_tsvector('english', coalesce(body, '')), 'B')"
    );
});

Pull Request: #59004

Виправлення помилок і покращення

Queue & Jobs:

Database:

HTTP & Filesystem:

Console & Views:

Інше:

Посилання

Популярні

Logomark Logotype

Обробка геопросторових даних за допомогою Laravel Magellan

Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!

Logomark Logotype

Інтеграція Laravel Socialite з бібліотекою Google Client PHP

Ви хочете навчитися, як інтегрувати Google OAuth у вашому проекті Laravel, використовуючи Socialite? Дізнайтеся, як налаштувати доступ до сервісів Google, таких як Календар, у нашій сьогоднішній статті

Logomark Logotype

Що нового в PHP 8.5

PHP 8.5 обіцяє безліч нових можливостей, таких як оператор Pipe, функції `array_first()` та `array_last()`, а також нове розширення URI. Чи готові ви дізнатися, як ці функції можуть спростити вашу розробку? Читайте далі, щоб дізнатися більше про ці захоплюючі нововведення