OrWhereHas отменил мое другое условие Where

Итак, я пытаюсь выполнить запрос, отфильтрованный по диапазону дат. Проблема в том, что мне нужно также выполнить запрос orWhereHas, который в настоящее время не подчиняется моему запросу whereBetween.

Итак, у меня есть 2 таблицы Promos и Member_Promo. Чтобы получить предстоящие акции для пользователя, я использую такую ​​​​функцию, как Auth::user()->upcomingPromos('ytd'). Функция выглядит так:

public function upcomingPromos($type)
    {
        switch ($type) {
            case 'ytd':
                $range = [Carbon::today(), Carbon::now()->endOfYear()];
                break;

            case 'mtd':
                $range = [Carbon::today(), Carbon::now()->endOfMonth()];
                break;
        }


        return Promo::where('owner_id', $this->id)
            ->whereBetween('date', $range)
            ->orWhereHas('members', function ($query) {
                $query->where('user_id', $this->id);
            })
            ->oldest('date')
            ->get();
    }

Я хочу, чтобы конечным результатом были все промо-акции между диапазонами дат, в которых находится пользователь:

  • а.) владелец (промо-таблица с owner_id)

  • б.) член (таблицаmembers_promo с user_id).

    Таким образом, список будет состоять из всех рекламных акций, частью которых они являются, между диапазоном дат.

В промо-таблице есть owner_id и date, по которым я ищу. Таблица members_promo — это просто сводка с user_id и promo_id. Проблема связана с тем, что orWhereHas не ограничивает этот запрос диапазоном дат. Поэтому, если пользователь является участником акции, которая не входит в этот диапазон, он все равно возвращается, когда не должен.

Я думаю, вы захотите вложить свои whereBetween и orWhereHas в вызов where(function($query) { }).

ceejayoz 21.05.2019 22:23

whereBetween ищет столбец даты, которого нет в сводной таблице, поэтому не знаю, как это сделать. $query->whereBetween('date', $range) я думаю, это не сработает, так как этого столбца в этой таблице не существует

Packy 21.05.2019 22:30

На самом деле это так работало? Я думаю, я просто предположил, что это не так.

Packy 21.05.2019 22:32

Laravel довольно умен в этих вещах. :-) Если это решило вашу проблему, дайте мне знать, и я добавлю ее в качестве ответа.

ceejayoz 21.05.2019 22:51

Умнее меня! Так и было. Мне просто нужно было добавить use ( $range ) и передать whereBetween

Packy 21.05.2019 22:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
5
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Замена get() на toSql() очень удобна для отладки такого рода проблем с запросами — она покажет вам SQL, который обрабатывается и выполняется вашими вызовами построителя запросов.

В вашем случае объединение двух параметров, которые вы хотите OR вместе, в where(function($query) { }) делает свое дело. Под капотом это помещает два условия в боковые круглые скобки в результирующем запросе.

return Promo::where('owner_id', $this->id)
    ->where(function($q) use ($range) {
        $q->whereBetween('date', $range)
            ->orWhereHas('members', function ($query) {
                $query->where('user_id', $this->id);
            });
    })
    ->oldest('date')
    ->get();

Другие вопросы по теме