Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

tasninta's avatar

Trying to get all products with the category_id

Hi, I am trying to get all products with the specific category_id I have a relationship between the categories and the products, with a pivot table category_product. In this pivot table there are 2 id's the category_id and the product_id.

Now I am trying to show the products from the specific category Example: category toys is attached to 1 product I only want to show the products for the category toys and not the other products for other categories.

I tried something in my view and controller but I get nothing back I hope someone can help me out!

This is my view:

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>Categoriën:</h1>
        @foreach ($products as $product)
            @if ($product->category_id == 1 )
                @continue
                <li>{{ $product->id }} {{ $product->name }}</li>
            @endif
        @endforeach
    </div>
@endsection

This is my shop controller:


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Category;
use \App\Product;

class ShopController extends Controller
{
  public function index(Request $request)
  {
    $categories = Category::with('products')->get();
    return view('shop.index', compact('categories'));
  }

  public function category1(Request $request)
  {
    $products = Product::with('categories', $request->get('category_id'));
    return view('shop.1', compact('products'));
  }
}

0 likes
6 replies
Vilfago's avatar

If your view is shop.index you don't have products variable.

If your view is shop.1 you get too many rows if you want only category 1.

I guess it's "category 1" so, I suggest the following :

  • more abstraction
  • less charge on DB
//Controller 

 public function category(Request $request)
  {
    $category = Category::with('products')->find($request->get('category_id'));
    return view('shop.1', compact('category'));
  }


//view
@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>Categoriën:</h1>
        @foreach ($category->products as $product)
                <li>{{ $product->id }} {{ $product->name }}</li>
            @endif
        @endforeach
    </div>
@endsection

It's a first step, you can do better in passing an argument in the route, and use this one instead of $request->get('category_id')

manelgavalda's avatar

First, you need to create a belongsToMany relation in your Category model. https://laravel.com/docs/5.7/eloquent-relationships#many-to-many:

public function products()
{
    return $this->belongsToMany(Product::class);
}

Then in your controller you can use:

  public function category1(Request $request)
  {
    $products = Category::find($request->category_id)->products;

    return view('shop.1', compact('products'));
  }

And finally you don't need the if in the view because you are just retrieving the products from the request category_id:

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>Categoriën:</h1>
        @foreach ($products as $product)
            <li>{{ $product->id }} {{ $product->name }}</li>
        @endforeach
    </div>
@endsection
tasninta's avatar

@Vilfago I tried to add your solution but I get the following error

Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) Call to undefined function App\Http\Controllers\find()

Vilfago's avatar

sorry, I missed a character.

I update my message above

tasninta's avatar

@Vilfago

Thanks!

I get the next error now:

Invalid argument supplied for foreach() (View: /home/vagrant/code/resources/views/shop/1.blade.php)

I gues the foreach is not right?

Vilfago's avatar
//Controller 

 public function category(Request $request)
  {
    $category = Category::with('products')->find($request->get('category_id'));
    dd($category); //Add this line
    return view('shop.1', compact('category'));
  }

What do you get ?

Please or to participate in this conversation.