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

johnef_sh's avatar

Select from three tables using eloquent

I have three tables

service_cats (id - cat_name)
service_sub_cats (id - cat_id - sub_cat_name)
sub_cat_contents (id - sub_cat_id - title - content)

and I made this relations

serviceCat

public function serviceSubCat()
    {
        return $this->hasMany('ServiceSubCat');
    }

serviceSubCat

public function ServicesCat()
    {
        return $this->belongsTo('ServiceCat', 'cat_id');
    }

    public function ssContent()
    {
        return $this->hasMany('SubCatContent');
    }

subCatContent

public function ssCat()
    {
        return $this->belongsTo('ServiceSubCat', 'sub_cat_id');
    }

I need to grape data from the three tables to use them.

here is my controller

public function show($id)
    {
        $serCat = ServiceCat::where('id', $id)->first();
        $getId = $serCat->sub_status;
        if ($getId == 1) {
            $subCats = ServiceSubCat::with('ssContent')->where('cat_id', $id)->get();
            //dd($subCats);
            return View::make('portal.services.servicesDetailsList', compact('serCat', 'subCats'));
        } else {
            return View::make('portal.services.servicesDetails');
        }
    }

now I get Error

    Column not found

I need to get the cat_name, sub_cat_name, title, content

0 likes
15 replies
martinbean's avatar

@johnef_sh Could you not just grab your products, and eager load the sub-category and category relations?

$products = Product::with('subCategory.category')->get();
<ul>
  @foreach($products as $product)
    <li>{{ $product->name }} is in {{ $product->subCategory->name}} sub-category and {{ $product->subCategory->category->name }} category</li>
  @endforeach
</ul>
1 like
tomopongrac's avatar

Try with this ...

public function serviceSubCat()
    {
        return $this->hasMany('ServiceSubCat', 'cat_id');
    }

public function ssContent()
    {
        return $this->hasMany('SubCatContent', 'sub_cat_id');
    }
johnef_sh's avatar

@tomi I just tried this part but got

Undefined property: Illuminate\Database\Eloquent\Collection::$title
tomopongrac's avatar

can you post your view code where you call title property

johnef_sh's avatar

@martinbean sorry didn't get this

you mean that I cloud do something like this

$serCat = ServiceCat::where('id', $id)->with('serviceSubCat.ssContent')->first();

I try this and no luck

johnef_sh's avatar

@tomi yes I did something like this and worked thanks guys so much

martinbean's avatar

@johnef_sh Be careful with @tomi’s solution: it suffers from N+1 problem, so if you have a lot of categories with a lot of sub-categories with a lot of products, that’s going to generate a lot of SQL statements.

1 like
tomopongrac's avatar

@martinbean

i think that he uses relationship, bellow is code from firt post

$subCats = ServiceSubCat::with('ssContent')->where('cat_id', $id)->get();
johnef_sh's avatar

Can anyone describe more about this N+1 issue and how to avoid this? thanks @martinbean for informing me about that

martinbean's avatar

@johnef_sh It’s basically doing a query in a loop.

If you have one query that returns 10 results, and then loop over the 10 loops and do a query in each iteration to get some other data, then that’s a total of 11 queries executed. So N is the number of iterations, plus the original query, ergo N+1.

You’ll actually have a worse problem as you’ll have two levels of looping (one loop to get sub-categories, and then a loop inside that one to get a sub-category’s products).

1 like
johnef_sh's avatar

I understand the issue Thanks for @martinbean and @tomi but any solution for this issue I saw Eager Loading and I am reviewing it now if you guys can suggest any solution, thanks again

johnef_sh's avatar

I edit my code now dose this solves the issue

public function show($id)
    {
        $serCat = ServiceCat::where('id', $id)->with('serviceSubCat.ssContent')->first();
        $getId = $serCat->sub_status;
        if ($getId == 1) {
            return View::make('portal.services.servicesDetailsList', compact('serCat'));
        } else {
            return View::make('portal.services.servicesDetails');
        }
    }

thanks

Please or to participate in this conversation.