Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

376
Views
Laravel whereHas relation where column can be equal to any in array but no other

I'm trying to build an Eloquent query to find a model that has relations where their column is equal to one of the given values, but no other. For example, a model could have several relations those column contains one of the given values, but have another relation that doesn't and should therefore be omitted.

All I have so far is a whereHas query that finds the models whose relations contain the values. This works exactly as it should, but I want to omit the models that contain a relation without these values, even if they have a relation that does.

$query->whereHas('conditions', function($query) use ($category_ids) {
  $query->where('conditionable_type', EmployeeCategoryOption::class)
        ->whereIn('conditionable_id', $category_ids);
});

I've searched the docs but can't find any Eloquant method that does what I'm after.

Thanks for your time.

EDIT (example scenario)

Conditions table:

id | conditionable_id | option_id
1  | 1                | 1
2  | 2                | 1
3  | 3                | 1
4  | 3                | 2
5  | 4                | 3

I would like to get all of the options that have a condition with a conditionable_id equal to 3 or 4 and no others. In the above table this would return option's 2 and 3 as option 1 also has conditionable_id's 1 and 2.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

If you have the opposite of the $category_id as $notCategoryIds

$query->whereDoesntHave('conditions', function($query) use ($notCategoryIds) {
    $query->where('conditionable_type', EmployeeCategoryOption::class)
        ->whereIn('conditionable_id', $notCategoryIds);
})->whereHas('conditions', function($query) {
    $query->where('conditionable_type', EmployeeCategoryOption::class);
})

If you dont have the invert category list, do it like this.

$query->whereDoesntHave('conditions', function($query) use ($category_id) {
    $query->where('conditionable_type', EmployeeCategoryOption::class)
        ->whereIn(
            'conditionable_id', 
            \DB::table('conditionable_option')->where('conditionable_type', EmployeeCategoryOption::class)
                ->whereNotIn('conditionable_id', $category_id)
                ->pluck('conditionable_id')->toArray();
        );
})->whereHas('conditions', function($query) {
    $query->where('conditionable_type', EmployeeCategoryOption::class);
})

You can change that pluck query inside to a query builder form instead of a fetch result query to make it faster using some joins and aliases.

over 4 years ago · Santiago Trujillo Report

0

You can use addSelect() to only add the models you need based on your query.

$query->whereHas('conditions', function($query) use ($category_ids) {
  $query->where('conditionable_type', EmployeeCategoryOption::class)
        ->whereIn('conditionable_id', $category_ids);
})->addSelect(['conditions' => Condition::select('field')
    ->whereColumn('your_field_id', 'condition.id')
    ->where('conditionable_type', EmployeeCategoryOption::class)
    ->whereIn('conditionable_id', $category_ids);
]);

You could refactor the addSelect() to a custom scope function on your model.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!