skip to Main Content

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.

UPD

So the problem wasn’t there =) 'details' just wasn’t filled in my Request.
also my $query was a string, not array, so I called json_decode on it.

Code above retrieves Models belonging to detail with id=1 AND to detail with id=2 and so on.

But I think there might be better solution so I’ll leave this question open

UPD 2

also changed this

$innerQuery->where('detail_id',  $detailId);

to this

$innerQuery->where('id',  $detailId);

so here is needed to pass columns we have in ‘details’ table, not columns from pivot table

3

Answers


  1. Chosen as BEST ANSWER

    Found solution to my problem here. So it seems like there is no better solution(


  2. 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));
    
    Login or Signup to reply.
  3. 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);
                }
            });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search