Итак, я пытаюсь выполнить запрос, отфильтрованный по диапазону дат. Проблема в том, что мне нужно также выполнить запрос 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
ищет столбец даты, которого нет в сводной таблице, поэтому не знаю, как это сделать. $query->whereBetween('date', $range)
я думаю, это не сработает, так как этого столбца в этой таблице не существует
На самом деле это так работало? Я думаю, я просто предположил, что это не так.
Laravel довольно умен в этих вещах. :-) Если это решило вашу проблему, дайте мне знать, и я добавлю ее в качестве ответа.
Умнее меня! Так и было. Мне просто нужно было добавить use ( $range ) и передать whereBetween
Замена 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();
Я думаю, вы захотите вложить свои
whereBetween
иorWhereHas
в вызовwhere(function($query) { })
.