За замовчуванням масова дія завантажує всі вибрані моделі в пам'ять і передає Eloquent-колекцію в action(). Коли користувач натискає «вибрати все» на таблиці з 200 000 рядків, це легко перевищує ліміт пам'яті PHP.
Порційна обробка:
use Filament\Actions\BulkAction;
use Illuminate\Support\LazyCollection;
BulkAction::make('archive')
->chunkSelectedRecords(250)
->action(function (LazyCollection $records) {
$records->each->update(['archived_at' => now()]);
})
Записи підтягуються пачками, $records стає LazyCollection - пам'ять стала, а код майже не змінюється.
Без завантаження моделей взагалі:
use Illuminate\Support\Collection;
BulkAction::make('archive')
->fetchSelectedRecords(false)
->action(fn (Collection $records) => Order::whereKey($records)->update(['archived_at' => now()]))
Тут $records - лише ідентифікатори, а оновлення - один SQL-запит.
Ціна fetchSelectedRecords(false). Filament завантажує моделі не просто так:
- щоб перевірити політику для кожного запису (
authorizeIndividualRecords('update')); - щоб спрацювали події моделі (
updating,deleted, спостерігачі, журнал активності, очищення кешу, Scout-індексація).
Масовий update()/delete() через запит обходить і те, і те. Для DeleteBulkAction це означає: без deleting-подій не видаляться файли, не оновиться пошуковий індекс, не запишеться аудит.
Як обирати:
| Потреба | Підхід |
|---|---|
| потрібні політики й події, записів сотні | за замовчуванням |
| потрібні політики й події, записів тисячі | chunkSelectedRecords() |
| чиста операція над даними, подій немає | fetchSelectedRecords(false) |
| дуже довга операція | поставити джобу в чергу з ідентифікаторами |
Звіт про часткові невдачі. Якщо частина записів не обробилася, $action->reportBulkProcessingFailure() додасть причину в підсумкове сповіщення («3 з 50 замовлень не вдалося архівувати»), а authorizeIndividualRecords() так само повідомляє про записи, відкинуті політикою.
Довгі операції в HTTP-запиті ризикують тайм-аутом. Для них краще: дія ставить джобу (Bus::batch по пачках ідентифікаторів) і надсилає сповіщення в базу даних, коли все готово.