Home > Net >  How to access Inverse Model Relationship when printing data in foreach loop at Blade
How to access Inverse Model Relationship when printing data in foreach loop at Blade

Time:02-16

Lets say I have an Attribute Model like this:

class Attribute extends Model
{
    public function group()
    {
        return $this->belongsTo(Group::class);
    }
}

And a Group Model like this:

class Group extends Model
{
    public function attributes()
    {
        return $this->hasMany(Attribute::class);
    }
}

So there's One To Many relationship between these two Models and every attribute has a group_id which is stored at the DB:

enter image description here

And I'm printing attributes at Blade like this:

Controller:

public function index()
    {
        $attributes = Attribute::all();
        return view('admin.attributes.index', compact(['attributes']));
    }

Now I want to know how to access the attributes() function at Group Model when using a foreach loop of all $attributes.

For example, here is my Blade:

@foreach($attributes as $attribute)
    @php 
        $groupInfo = \App\Models\Attribute\Group::where('id',$attribute->group_id)->first();
        $groupAttrs = $groupInfo->attributes;
    @endphp

    @foreach($groupAttrs as $gr_attr)
        {{ $gr_attr->name }}
    @endforeach
@endforeach

So in this way, I can correctly access all the attributes that a group id is referenced with.

But I did this by calling the Model directly in the Blade and used @php ... @endphp. So this is NOT a good way.

So how can I access the Object related Model inversely and print data from it properly ?

CodePudding user response:

The way of fetching any kind of relationship in Laravel is to use with() method. It has very nice veriations, and advanced use cases. So I suggest you take a look at the documentation.

Firstly, querying in Blade should be the last option and should be avoid if it's possible. Let's say you have 10 groups, and 50 attributes. When you query the attributes in Blade, it will go to database for each group, and fetch the attributes seperately. Since you made a query to groups in the first place, you will end up 21 query, bunch of unnecesseraly loaded models, wasting memory, etc. So you shoul do that in the controller like so:

$groups = Group::with('attributes')->get();

in Blade

@foreach($groups as $group)
    @foreach($group->attributes as $attr)
       {-- your code --}
    @endforeach
@endforeach

or the connection will be opposite but the logic will be the same

$attributes = Attribute::with('group')->get();
@foreach($attributes as $attr)
    $attr->group
@endforeach

CodePudding user response:

Well first at all you are not using benefits of relations in laravel.

Controller :

public function index()
    {
        $groups = Group::with('attributes')->get();
        return view('admin.attributes.index', compact(['groups']));
    }

Blade:

@foreach($groups as $group)
    @foreach($group->attributes as $attribute)
        {{ $attribute->name }}
    @endforeach
@endforeach
  • Related