phplaravelone-to-manylaravel-5.8laravel-relations

Retrieving data based on One To Many Relationship


I have two tabled called categories and resources table.

Basically each resource has a category and the category id is saved on a column called resource_category_id in resources table.

So in order to setup One To Many relationship between the Models, I did these:

Category:

class Category extends Model
{
    protected $table = "categories";
    protected $guarded = [];
    
    public function resources()
    {
        return $this->hasMany(Resource::class);
    }
}

Resource:

class Resource extends Model
{
    protected $table = "resources";
    protected $guarded = [];
    
    public function category()
    {
        return $this->belongsTo(Category::class, 'resource_category_id');
    }
}

And now I want to show all categories and the resources and that have the same resource_category_id like this:

@php($menuCounter = 0)
@foreach($categories as $cat)
    <tr>
        <td style="text-align:center">{{ ++$menuCounter }}</td>
        <td style="text-align:center">{{ $cat->category_name }}</td>
        <td>
            <ul>
                @foreach($category->resources() as $resource)
                    <li><a href="{{ $resource->resource_link }}">{{ $ress->resource_name }}</a></li>
                @endforeach
            </ul>
        </td>
    </tr>
@endforeach

But now the categories are all appearing but the resources does not be shown and also no error returns!

So what's going wrong here?

How can I show the resources according to resource_category_id via Eloquent relationships methods?


Solution

  • Instead of:

    @foreach($category->resources() as $resource)
    

    do

    @foreach($category->resources as $resource)
    

    The first one is loading the builder, the second one the collection.

    You can also specify the foreign key for resources relationship in Category Model:

    public function resources()
    {
        return $this->hasMany(Resource::class, 'resource_category_id');
    }