whereHas и WHEREDOESN работают не так, как ожидалось, в laravel eloquent

#laravel #eloquent

#laravel #eloquent

Вопрос:

Мой запрос:

 Payment::whereHas('subscription',function($q)
   {
      $q->where('ends_at','>',today());
   })->orWhereDoesntHave('subscription')->where('user_id',1)->first();
 

Вывод:

 AppPayment {#4339
     id: 6,
     user_id: 317,
     package_id: 6,
     amount: 12500,
     phone: "01849744603",
     transaction_id: "F1234",
     confirmed: 1,
     created_at: "2020-11-29 14:29:08",
     updated_at: "2020-11-29 16:40:03",
   }
 

Моя логика такова: когда я совершаю платеж, создается подписка на определенный пакет на определенный срок, если администратор одобряет платеж. Я хочу получить платежную информацию пользователя, если он не подписан, но произвел платеж или срок его подписки не истек. Я написал приведенный выше код, который выдает мне вывод для первой платежной информации базы данных. Не для пользователя, указанного user_id в запросе. Как мне следует подойти? И в чем здесь проблема? Кто-нибудь может мне помочь?

Комментарии:

1. Вы хотите получать все платежи от пользователя? я думаю, что формулировка немного сложна для понимания, и что вы подразумеваете под запрошенным пользователем?

2. Под запрошенным пользователем я подразумеваю пользователя, указанного user_id в запросе.

Ответ №1:

Проблема, вероятно, связана с приоритетом в логических операторах в SQL. Ваш сгенерированный SQL будет псевдо-чем-то вроде этого.

 in (select * from subscriptions) OR ! in (select * from subscriptions) and user_id = 1
 

Обертывание вашего запроса в a where() с замыканием создаст круглые скобки в SQL вокруг первой части, и безопасный приоритет будет правильным.

 Payment::where(function ($query) {
    $query->whereHas('subscription', function($q)
    {
        $q->where('ends_at','>',today());
    })->orWhereDoesntHave('subscription');
})->where('user_id',1)->first();