Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

eggplantSword's avatar

Eloquent query not working as expected

I'm trying to filter using a query builder but I'm not getting the expected results. This is my code so far:

The $request->get('detail') is the user input to search by, on the model being searched the relationships are like this

 public function activations() {
        return $this->hasMany(Activation::class, 'dmm_report_id');
    }

    public function portabilities() {
        return $this->hasMany(Portability::class, 'dmm_report_id');
    }

//reverse relationships, both tables are simple pivots
//Activation
public function details() {
        return $this->belongsToMany(Detail::class, 'activation_details');
    }
//Portability
  public function details() {
        return $this->belongsToMany(Detail::class, 'portability_details');
    }
 if (!empty($request->get('detail'))) {
            $query->whereHas('activations', function ($query) use ($request) {
                $query->whereHas('details', function ($query) use ($request) {
                    $query->where('value', $request->get('detail'));
                });
            });

            $query->whereHas('portabilities', function ($query) use ($request) {
                $query->whereHas('details', function ($query) use ($request) {
                    $query->where('value', $request->get('detail'));
                });
            });
        }

Right now what is happening is: when I search for a detail that I know is in the activations, the search returns empty but as soon as I remove the portability part from the query it works and vise versa if I remove activations and leave portabilities. It'll do one or the other but not both. The detail could be in either relationship so if the search is '123' it should search in both details (if present) and return where either is a match.

What am I doing wrong?

0 likes
6 replies
tykus's avatar

You probably need an orWhereHas for the search, not the implicit AND

tykus's avatar
tykus
Best Answer
Level 104

@msslgomez no, on the outer one:

 if (!empty($request->get('detail'))) {
    $query->whereHas('activations', function ($query) use ($request) {
        $query->whereHas('details', function ($query) use ($request) {
            $query->where('value', $request->get('detail'));
        });
    });

    $query->orWhereHas('portabilities', function ($query) use ($request) {
        $query->whereHas('details', function ($query) use ($request) {
            $query->where('value', $request->get('detail'));
        });
    });
}
1 like
tykus's avatar

@msslgomez you should be able to use the dot-syntax to simplify querying the nested relations:

$query->whereHas('activations.details', function ($query) use ($request) {
    $query->where('value', $request->get('detail'));
})->orWhereHas('portabilities.details', function ($query) use ($request) {
    $query->where('value', $request->get('detail'));
});

Please or to participate in this conversation.