Tomjesch
Tomjesch

Reputation: 510

Multiline Eloquent query

I'm trying to filter my products based on selected filters and possibly a search term/word. My filters have a relationship with categories, which in their turn have a relation ship with my products. My code below only works (without the if statement checking for a search term/word) when everything is chained together, but when I try to break the query into multiple lines (which I've read is possible, right?) it returns an empty array.

Here's a my code:

// Create array from selected categories/filters
$filter_ids = explode(',', $request->get('cats'));

// Query for active products
$products = Product::where('active', '=', 1);
$products->with(['categories' => function($query) use ($filter_ids) {
    // Query for active categories
    $query->where('active', 1)->whereHas('filters', function ($query)  use ($filter_ids) {
        // Query for the selected filters from the request 
        $query->whereIn('id', $filter_ids);
    });
}]);

// Check for search term/word
if ($request->get('q')) {
    $q = $request->get('q') ? urldecode($request->get('q')) : null;
    $products->where('title', 'LIKE', "%{$q}%");
}

// Limit to 10 items and get results
$products->limit(10)->get();

return response()->json([
    'status' => 'success',
    'response' => $products
], 200);

Upvotes: 0

Views: 1003

Answers (2)

Lukas
Lukas

Reputation: 1123

I think you could but don't need to query all products with title first, before adding the relationships. But whats wrong here is that you must store the result of get() in a variable before adding it to your json response body:

Try to do something like:

if ($request->get('q')) {
$q = $request->get('q') ? urldecode($request->get('q')) : null;
$products->where('title', 'LIKE', "%{$q}%");
}

   $products->with(['categories' => function($query) use ($filter_ids) {
    // Query for active categories
    $query->where('active', 1)->whereHas('filters', function ($query)  use ($filter_ids) {
        // Query for the selected filters from the request 
        $query->whereIn('id', $filter_ids);
    });
   }]);


$response = $products->limit(10)->get();

return response()->json([
    'status' => 'success',
    'response' => $response
], 200);

Upvotes: 1

Tomjesch
Tomjesch

Reputation: 510

Lukas' answer led me to do some more debugging and eventually solving my problem, though it was not the position of the if statement checking if there's a search term/word.

The problem lies in the following line:

$products->limit(10)->get();

I needed to store the retrieved results from the get(); method in another variable, in my case:

$response = $products->limit(10)->get();

I eventually ended up with the following working code:

// Create array from selected categories/filters
$filter_ids = explode(',', $request->get('cats'));

// Query for active products
$products = Product::where('active', '=', 1);
$products->with(['categories' => function($query) use ($filter_ids) {
    // Query for active categories
    $query->where('active', 1)->whereHas('filters', function ($query)  use ($filter_ids) {
        // Query for the selected filters from the request 
        $query->whereIn('id', $filter_ids);
    });
}]);

// Check for search term/word
if ($request->get('q')) {
    $q = $request->get('q') ? urldecode($request->get('q')) : null;
    $products->where('title', 'LIKE', "%{$q}%");
}

// Limit to 10 items, get results and store in '$response'
$response = products->limit(10)->get();

return response()->json([
    'status' => 'success',
    'response' => $response
], 200);

Upvotes: 0

Related Questions