简体   繁体   中英

Adding filters or additional Where Clauses to Query with joins in Laravel 5.4

Hello Stack overflow community

I currently have the following code ( example 1 ), which will return the list of restaurants with their food type and area, using additional joins.

I need to add more WHERE clauses, but only if there is any to be passed like ( example 2 )

The search may only have a name or part of a name, maybe they just want to search by area or food type.

example 1

$q = Input::get ( 'q' );
    if($q != ""){
        $restaurants = DB::table('restaurant')
                ->where ( 'restaurant.name', 'LIKE', '%' . $q . '%' )
                ->join  ( 'area', 'restaurant.area_id', '=', 'area.id' )
                ->join  ( 'food_type', 'restaurant.food_type_id', '=', 'food_type.id' )
                ->select( 'restaurant.*', 'food_type.name as food_type_name', 'area.slug as area_slug', 'area.name as area_name')
                ->paginate(2);
        $pagination = $restaurants->appends ( array (
                'q' => Input::get ( 'q' ) 
        ) );
    } else {
        $restaurants = DB::table('restaurant')
                ->join  ( 'area', 'restaurant.area_id', '=', 'area.id' )
                ->join  ( 'food_type', 'restaurant.food_type_id', '=', 'food_type.id' )
                ->select( 'restaurant.*', 'food_type.name as food_type_name', 'area.slug as area_slug', 'area.name as area_name')
                ->paginate(15);
    }

example 2

if ($q){
    ->where ( 'restaurant.name', 'LIKE', '%' . $q . '%' )
}
if ($request->has('area')){
    ->where('area', $request->input('area'));
}

if ($request->has('foodtype')){
    foreach(foodtype as name => value)
        ->where('foodtype', $value);
}

I feel there should be a way to do this, rather than writing out a different query for each possible outcome

I have tested the response by Unamata Sanatarai, ( Example 3 but this came with an error:

Call to undefined method Illuminate\\Database\\Query\\Builder::appends()

I have tried replacing ->paginate() with ->get() (as mentioned in another post), but i receive the same error

Example 3

$q = Input::get ( 'q' );
    if($q != ""){
        $restaurants = DB::table('restaurant');
        $restaurants->where ( 'restaurant.name', 'LIKE', '%' . $q . '%' );
        $restaurants->join  ( 'area', 'restaurant.area_id', '=', 'area.id' );
        $restaurants->join  ( 'food_type', 'restaurant.food_type_id', '=', 'food_type.id' );
        $restaurants->select( 'restaurant.*', 'food_type.name as food_type_name', 'area.slug as area_slug', 'area.name as area_name');
        $restaurants->paginate(15);

        $pagination = $restaurants->appends ( array (
                'q' => Input::get ( 'q' ) 
        ) );
    } else {
        $restaurants = DB::table('restaurant')
                ->join  ( 'area', 'restaurant.area_id', '=', 'area.id' )
                ->join  ( 'food_type', 'restaurant.food_type_id', '=', 'food_type.id' )
                ->select( 'restaurant.*', 'food_type.name as food_type_name', 'area.slug as area_slug', 'area.name as area_name')
                ->paginate(15);
    }

Example 4 Will explain my latest error

Undefined property: Illuminate\\Database\\MySqlConnection::$main_image

$main_image is one of the fields in the database - this worked fine up until i changed the query to example 3

Example 4 shows the new code with links, this produces the error

Example 4

$restaurants = DB::table('restaurant');
        $restaurants->join  ( 'area', 'restaurant.area_id', '=', 'area.id' );
        $restaurants->join  ( 'food_type', 'restaurant.food_type_id', '=', 'food_type.id' );
        $restaurants->select( 'restaurant.*', 'food_type.name as food_type_name', 'area.slug as area_slug', 'area.name as area_name');
        $restaurants->paginate(15)->links();

You can do it just about as you've described in the example 2.

Until you call the last method, you can continue to manipulate your Builder.

You can modify your Query Builder until you call ->paginate() or ->get() or ->first() ...

$restaurants = DB::table('restaurant');
if ($q){
    $restaurants->where ( 'restaurant.name', 'LIKE', '%' . $q . '%' )
}
if ($request->has('area')){
    $restaurants->where('area', $request->input('area'));
}

if ($request->has('foodtype')){
    foreach(foodtype as name => value)
        $restaurants->where('foodtype', $value);
}

return $restaurants->paginate();

In order to answer your Second question, the one about the appends() error.

The appends() method can be called on paginate() results. At the moment, you are continuing to call it on the query builder.

The function ->paginate() , returns pagination from the $restaurants query builder .

// ...
$pagination = $restaurants->paginate();
$pagination->appends(array (
    'q' => Input::get ( 'q' ) 
) )->links();

https://laravel.com/docs/5.5/pagination#displaying-pagination-results

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM