Próbuję dodać warunek gdzie w zagnieżdżonej relacji mojego modelu, coś takiego:

SELECT *
FROM users u
INNER JOIN products p ON p.user_id = u.id
WHERE p.created_at > '2019-12-01';

To, co robię w Laravel, to:

$this->builder->where('products.date', '>', '2019-12-01');

I oczywiście działa doskonale. Problem w tym, że jeśli zamienię go na:

$this->builder->whereHas('products', function ($query) {
  $query->where('date', '>', '2019-12-01');
});

Nie działa już zgodnie z oczekiwaniami. Dzieje się tak, ponieważ w drugim przypadku laravel dodaje następujące zapytanie:

and exists (SELECT * from products where users.id = products.user_id and date > '2019-12-01') 

Więc w tym przypadku mój JOIN nie jest stosowany do mojego warunku gdzie i otrzymuję zbyt wiele wyników.

Czy istnieje sposób na zastosowanie zagnieżdżonego warunku where przy użyciu elokwentnych relacji, który działałby tak, jak w moim pierwszym przykładzie?

2
khernik 20 grudzień 2019, 08:04
2
Zgodnie z tym postem, surowe zapytanie będzie and exists (SELECT * from products where users.id = products.user_id and date > '2019-12-01') , myślę, że zapomniałeś zamieścić jakiś kod.
 – 
TsaiKoga
20 grudzień 2019, 08:32
1
Tak jak join products przed $this->builder->whereHas? czy możesz opublikować swój kod na temat $this->builder
 – 
TsaiKoga
20 grudzień 2019, 08:49

1 odpowiedź

Użyj with dla tego rodzaju scenariusza.

$this->builder->with(['products'=>function ($query) {
  $query->where('date', '>', '2019-12-01');
}]);

Dzięki temu otrzymasz users z products. Ale products przefiltrowano jako date > 2019-12-01

Możesz to zrobić również za pomocą carbon i whereDate.

$date =Carbon\Carbon::parse('2019-12-01')->format('Y-m-d');

$this->builder->with(['products'=>function ($query) use($date) {
  $query->whereDate('date', '>', $date);
}]);
2
Dilip Hirapara 20 grudzień 2019, 08:34
To trochę działa, ponieważ mam dostęp do wyników, ale nie jest to stosowane jako warunek WHERE - po prostu daje mi przefiltrowane dane, które mogę uzyskać osobno.
 – 
khernik
20 grudzień 2019, 08:25
To zapytanie jest takie samo jak pierwsze zapytanie sprzężenia. a jeśli sprawdzisz dziennik zapytań, możesz dowiedzieć się, jakie było ostatnio wykonane zapytanie, sprawdź ten link. artisansweb.net/how-to-log-query-in-laravel a jeśli chcesz użyć warunku gdzie na relacji, musisz postępować zgodnie z konstruktorem zapytań, a nie relacją.
 – 
Dilip Hirapara
20 grudzień 2019, 08:30