Mam zapytanie filtrujące, w którym sprawdza trzy parametry id , słowa kluczowe i stan . Działa całkowicie dobrze, gdy uruchamiam to zapytanie w MySQL, ale kiedy próbuję uruchomić je przez kreator zapytań Laravel, pobiera wszystkie wyniki tego id .

Oto zapytanie, które uruchamiam w MySQL (i działa dobrze, jak wspomniałem):

SELECT * FROM `poems`
WHERE book_id = 2
AND p_english_keywords LIKE '%freedom%'
AND p_status = 1

A oto kod kreatora zapytań Laravel:

$poems = Poems
     ::where('book_id', '=', $filter, 'AND', 'p_english_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
     ->orWhere('book_id', '=', $filter, 'AND', 'p_spanish_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
     ->orWhere('book_id', '=', $filter, 'AND', 'p_german_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
     ->orWhere('book_id', '=', $filter, 'AND', 'p_urdu_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
     ->paginate(10);

To zapytanie wygląda zupełnie dobrze i działa dobrze, jeśli użytkownik usunie filtr. Wyszukuje słowa kluczowe w języku użytkownika. Jednak za każdym razem, gdy użytkownik stosuje filtr, wyświetla wszystkie wyniki z przefiltrowanej książki zamiast określonych słów kluczowych w tej książce. Proszę pomóż!

-1
Saud 20 listopad 2019, 23:08
orWhere zajmuje tylko do 3 argumenty? Zamiast tego powinieneś użyć zamknięcia
 – 
Brian Thompson
20 listopad 2019, 23:41
Tak, podpis dla where() to where($column, $operator = null, $value = null, $boolean = 'and'), więc ignoruje wszystko po 'AND'. Jeśli uruchomisz ->toSql() zamiast ->paginate(), możesz zobaczyć wygenerowany SQL i trochę lepiej go debugować. where() również akceptuje tablicę jako pierwszy parametr, ale musisz przekazać where([], null, null, 'AND'), aby działała poprawnie.
 – 
Tim Lewis
20 listopad 2019, 23:45
Nie wiem, czy zajmuje to trzy parametry, czy więcej. Właściwie jestem nowy w Laravelu i wciąż się uczę. Przeczytałem dokumentację i jest w niej napisane, że możesz użyć 3 parametrów dla podstawowej klauzuli where(), czytanie, które założyłem, może zająć więcej i jakoś się udało. Oznacza to, że to zapytanie powinno działać i działa całkowicie poprawnie Poems::where( 'p_english_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1). Nie wiem dlaczego, ale działa.
 – 
Saud
24 listopad 2019, 15:41
@TimLewis, sprawdziłem zapytanie za pomocą toSql() i pomogło to w debugowaniu i Tak, wiem o tablicach jako parametrach. Uruchomiłem kilka zapytań za pomocą parametrów tablicowych, takich jak TableName::where(['column' => $value, 'column2' => $value2]); i zadziałało to dla mnie. Mam nadzieję, że zrozumiałem, co powiedziałeś.
 – 
Saud
24 listopad 2019, 16:24

1 odpowiedź

Nie jestem pewien, dlaczego Poems::where('book_id', '=', $filter, 'AND', 'p_english_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1) kiedykolwiek zadziałał, ponieważ ta składnia nie znajduje się w dokumentacja gdziekolwiek, więc przepiszę Twoje zapytanie.

$poems = Poems::where(function ($q) use ($filter, $query) {
    $q->where([
        ['book_id', '=', $filter],
        ['p_english_keywords', 'like', '%'.$query.'%'],
        ['p_status', '=', 1],
    ]);
})
->orWhere(function ($q) use ($filter, $query) {
    $q->where([
        ['book_id', '=', $filter],
        ['p_spanish_keywords', 'like', '%'.$query.'%'],
        ['p_status', '=', 1],
    ]);
})
->orWhere(function ($q) use ($filter, $query) {
    $q->where([
        ['book_id', '=', $filter],
        ['p_german_keywords', 'like', '%'.$query.'%'],
        ['p_status', '=', 1],
    ]);
})
->orWhere(function ($q) use ($filter, $query) {
    $q->where([
        ['book_id', '=', $filter],
        ['p_urdu_keywords', 'like', '%'.$query.'%'],
        ['p_status', '=', 1],
    ]);
})
->paginate(10);

Jednak ponieważ zawsze tworzysz te same filtry (book_id = $filter i p_status = 1), myślę, że można to jeszcze bardziej zredukować:

$poems = Poems::where([
    ['book_id', '=', $filter],
    ['p_status', '=', 1],
])
->where(function ($q) use ($query) {
    $q->where('p_english_keywords', 'like', '%'.$query.'%')
    ->orWhere('p_spanish_keywords', 'like', '%'.$query.'%')
    ->orWhere('p_german_keywords', 'like', '%'.$query.'%')
    ->orWhere('p_urdu_keywords', 'like', '%'.$query.'%');
})
->paginate(10);

Używając toSql(), otrzymuję następujące zapytanie, którego, jak sądzę, szukasz:

select * from `poems`
where (
    `book_id` = ? and `p_status` = ?
)
and (
    `p_english_keywords` like ?
    or `p_spanish_keywords` like ?
    or `p_german_keywords` like ?
    or `p_urdu_keywords` like ?
)
2
IGP 20 listopad 2019, 23:40