Home > OS >  How to access one relation inside another relation in laravel?
How to access one relation inside another relation in laravel?

Time:03-15

I have a query in which I have eagar loaded two models using with function like this:

ModelA::with(['relationB', 'relationC.relationC.A'])->where(condition)->get();

So, ModelA has two relations like this:

public function B(){ return $this->blongsTo(B::class);}

public function C(){ return $this->blongsTo(C::class);}

Now, my requirement is that I want to add a condition in B() function like this:

    public function C() { 

     if($this->B->status) {
        return $this->blongsTo(C::class)->withTrashed();
     }
     return $this->blongsTo(C::class);
   }

But it return null on line this statement:

if($this->B->status) 

Here is the error message

Trying to get property 'status' of non-object

My ultimate requirement is that using one relation function I want to fetch deleted records and non deleted based on the condition, but somehow it is not working.

My laravel application version is 7.30.4.

CodePudding user response:

A relational function (such as your public function C()) works a bit of magic under the hood. This is because really it is designed to be called in a query way like you show already with the ::with(['relationB', ...]).

However, because of this, if you were to eager load C, then $this is not yet loaded as the full model, and therefore B is not defined (this is assuming that modelA always has a B relation). If you were to dd($this) while performing your query, you'd see that the result would be a model without any attributes.

Getting this to work from within a relational function (with the goal of eager loading) is very difficult. You're probably better off doing the logic elsewhere, with a second query for example. This is because within the relational function, there is no way to know who or what the potential target is. However, if you only use it after modelA is loaded, then it works without issues.

You can do some things with a whereHas, but then you'd still have to do 2 queries, or you can try and see if you can get it done with an SQL IF statement, but that will not result in a relation.

  • Related