laraveleloquentlaravel-livewireeloquent-relationshiphas-one

Laravel Eloquent Query WhereHas


I have the following code for reference

//MODEL_A

public function latest_B()
{
return $this->hasOne(B::class)->latest();
}
 public function Bs()
{
return $this->hasMany(B::class);
}

//Livewire

return A::where(function ($q1) {
            $q1->where('id',auth()->user()->id)
           ->orWhere('for',auth()->user()->email);
        })
        ->whereYear('created_at',$this->year)
        ->orWhereHas('latest_B',function($q2){
            $q2->where('att_for',auth()->user()->email)
            ->orWhere('tta_for',auth()->user()->id)
            ;
        })
        ->search($this->search)
        ->latest()
        ->paginate($this->perPage);

My problem is this query still returning model A with NOT latest model B .

I am expecting only to get 3 result, but it is returning 7.


Solution

  • on your model Function latest_b are you using that to get the latest item of B::class? If so then you can use Laravel's Has One Of Many Feature

    https://laravel.com/docs/10.x/eloquent-relationships#has-one-of-many

    public function latest_b(): HasOne
    {
        return $this->hasOne(B::class)->latestOfMany();
    }
    

    I don't really know your the data structure you have and the output of the query but if I understand your issue properly... try using this...

    if you can provide an answer to my comments above I will be able to give you a much more clear answer.

    return A::query()->whereYear('created_at',$this->year)
        ->where(function ($query) {
            $query->where(function ($q1) {
                $q1->where('id',auth()->user()->id)->orWhere('for',auth()->user()->email);
            })->orWhereHas('latest_B',function($q2){
                $q2->where('att_for',auth()->user()->email)->orWhere('tta_for',auth()->user()->id);
            })
        })
        ->search($this->search)
        ->latest()
        ->paginate($this->perPage);