У меня есть запрос с несколькими объединениями и глобальными областями действия для каждой модели, например:
SELECT *
FROM products p
WHERE EXISTS(
SELECT *
FROM orders o
WHERE o.user_id = 4
AND o.status_id = 1
AND o.user_id = 3
AND EXISTS(
SELECT *
FROM suborders s
WHERE s.status_id = 2
)
);
Это означает, что я могу просто написать несколько whereHas
операторов, и мой запрос будет иметь несколько вложенных EXIST
, но все глобальные области (например, user_id
в таблице orders
) будут применены автоматически:
$this->builder->whereHas('orders', function ($q) {
$q->where('status_id', '=', 1)
->whereHas('suborder', function ($q) {
$q->where('status_id', '=', 2);
});
});
Проблема в том, что это медленно, было бы гораздо лучше иметь что-то с простыми JOIN
s вместо уродливых вложенных EXIST
предложений:
SELECT *
FROM products p
INNER JOIN orders o ON p.order_id = o.id
INNER JOIN suborders s ON o.id = s.order_id
WHERE o.status_id = 1
AND u.user_id = 3
AND s.status_id = 2;
Проблема в том, что мне нужно использовать построитель запросов, чтобы присоединиться к ним:
$this->builder->join('orders', 'products.order_id', '=', 'orders.id')
->join('suborders', 'orders.id', '=', 'suborders.order_id')
->where('orders.status_id', 1)
->where('suborders.id', 2);
И это не будет включать ни одну из моих глобальных областей применения на моделях Order
и Suborder
. Мне нужно сделать это вручную:
$this->builder->join('orders', 'products.order_id', '=', 'orders.id')
->join('suborders', 'orders.id', '=', 'suborders.order_id')
->where('orders.status_id', 1)
->where('suborders.id', 2)
->where('orders.user_id', 3);
Это плохо, потому что мне нужно реплицировать мои глобальные логи областей c каждый раз, когда я пишу такой запрос, в то время как whereHas
применяет их автоматически.
Есть ли способ присоединиться к таблице и автоматически применить все глобальные области действия из объединенной модели?