Елегантно обробляйте відсутні моделі за допомогою методу existsOr у Laravel

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 27 травня, 2025
В Laravel з'явився метод existsOr, який пропонує елегантне рішення для обробки ситуацій, коли запити до моделей не повертають результатів. Цей новий підхід спрощує логіку помилок та дозволяє визначати альтернативні дії на етапі запиту – дізнайтеся більше про його переваги в нашій статті

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

Метод existsOr дозволяє розробникам визначати поведінку за замовчуванням безпосередньо в ланцюжку запитів:

Model::where(...)
    ->existsOr(function () {
        // Виконати логіку, коли модель не існує
    });

Цей підхід особливо цінний у системах управління запасами:

class InventoryController extends Controller
{
    public function verifyStock($itemCode)
    {
        return Item::where('code', $itemCode)
            ->where('quantity', '>', 0)
            ->existsOr(function () use ($itemCode) {
                Log::warning("Перевірка запасів для недоступного товару: {$itemCode}");
 
                return response()->json([
                    'in_stock' => false,
                    'message' => 'Товар недоступний або закінчився'
                ], 404);
            });
    }
 
    public function reserveItem($itemId, $quantity)
    {
        return Item::where('id', $itemId)
            ->where('available_quantity', '>=', $quantity)
            ->existsOr(function () use ($itemId, $quantity) {
                throw new InsufficientStockException(
                    "Не можу зарезервувати {$quantity} одиниць товару {$itemId}"
                );
            });
    }
 
    public function updatePricing($itemId, $newPrice)
    {
        return Item::where('id', $itemId)
            ->where('status', 'active')
            ->existsOr(function () use ($itemId) {
                event(new PricingUpdateFailed($itemId));
 
                return redirect()
                    ->route('inventory.index')
                    ->with('error', 'Товар не знайдено або неактивний');
            });
    }
}

Метод existsOr також ефективно працює в сценаріях підписки та контролю доступу:

class SubscriptionController extends Controller
{
    public function accessFeature($userId, $featureId)
    {
        return Subscription::where('user_id', $userId)
            ->where('status', 'active')
            ->where('expires_at', '>', now())
            ->existsOr(function () use ($userId, $featureId) {
                // Логування спроби несанкціонованого доступу
                Log::notice("Доступ заборонений для користувача {$userId} до функції {$featureId}");
 
                // Перенаправлення на сторінку оновлення
                return redirect()
                    ->route('subscriptions.upgrade')
                    ->with('message', 'Ця функція потребує активної підписки');
            });
    }
 
    public function validateAccess($organizationId, $userId)
    {
        return OrganizationMember::where('organization_id', $organizationId)
            ->where('user_id', $userId)
            ->where('status', 'approved')
            ->existsOr(function () {
                abort(403, 'Доступ заборонений до цієї організації');
            });
    }
}

Метод existsOr дозволяє зробити код більш чистим, виключаючи необхідність окремих перевірок на існування, за якими слідує умовна логіка. Замість того, щоб писати:

$exists = Model::where(...)->exists();
if (!$exists) {
    // Обробка відсутності
}

Тепер ви можете написати:

Model::where(...)
    ->existsOr(function () {
        // Обробка відсутності
    });

Такий підхід зберігає потік запиту та забезпечує чітке вирішення ситуацій із відсутніми моделями