Home > Software engineering >  Get model which has all specific related models
Get model which has all specific related models

Time:02-04

I have no idea how to solve my problem.

I have Model1 with relation:

class Model1 extends BaseModel
{
    public function details(): BelongsToMany
    {
        return $this->belongsToMany(
            Detail::class,
            'model1_details',
            'model1_id',
            'detail_id',
        );
    }
}

model1_details is my pivot table.

Also I have array of details ids like [1, 2, 3]. I need to fetch Model1 that belongs to ALL Detail with given ids.

I need to do this inside my filter. That's what I have inside my controller:

$builder = Model1::filter(new ModelListFilter($request));

and inside ModelListFilter:

protected function filter(): Builder
    {
        $request = $this->request;

        $request->whenFilled('details', function ($query) {
            //
        });

        return $this->builder;
    }

I've tried:

$request->whenFilled('details', function ($query) {
            foreach($query as $detailId) {
                $this->builder->whereHas('details', function (Builder $innerQuery) use ($detailId) {
                    $innerQuery->where('detail_id',  $detailId);
                });
            }
        });

But it returns all models Model1 even without any details.

CodePudding user response:

I can't see where you load the relationship with details. Not sure if you're missing a file, but in case you're not, load the relationship in the first part of the query with the eager loading with method:

$builder = Model1::with('details')->filter(new ModelListFilter($request));

CodePudding user response:

You are almost there but you still missing two things,

WhereIn list

to get model whereHas their details ids in a list you need to use WhereIn instead of looping the query

Eager load the details relationship

to get the details list with each model you have to use the with keyword to eager load the relationship

Solution

// builder
$builder = Model1::with('details')->filter(new ModelListFilter($request));

// filter
$request->whenFilled('details', function (array $details) {
       $this->builder->whereHas('details', function (Builder 
            $innerQuery) use ($details) {
                    $innerQuery->whereIn('detail_id',  $details);
            }
        });
  • Related