Home > OS >  Multiple Where Statements from Loop in Callback Function in Laravel/Eloquent
Multiple Where Statements from Loop in Callback Function in Laravel/Eloquent

Time:09-16

I'm trying to build a filter function that returns a list of Exchanges based on the features the user has a selected. Each feature has a unique slug, and the $featureSlugs contains an array of these slugs (strings).

$featureSlugs = ['security', 'mobile-app', '2FA'];

$exchanges = Exchange::whereHas('features', function ($q) use ($featureSlugs) {
                    $q->where('slug', $featureSlugs);
                })->get();

What's extremely strange is this query works for 1 feature or 2 features, but anything more than 2 it stops working and doesn't filter anymore.

I want the filter to get narrower and narrower, so using multiple where statements for each feature, returning only exchanges that have all the features the user selected. This is the code I'm trying and it's not working, but I think demonstrates what i'm trying to do:

$exchanges = Exchange::whereHas('features', function ($q) use ($featureSlugs) {
                    foreach($featureSlugs as $featureSlug)
                    {
                        $q->where('slug', $featureSlug);
                    }
                })->get();

How can i put multiple where statements for each featureSlug in the array?

CodePudding user response:

You're in the right direction. You just have to use whereIn or orWhere

$exchanges = Exchange::whereHas('features', function ($q) use ($featureSlugs) {
    $q->whereIn('slug', $featureSlugs);

    // This one is not optimal of course
    foreach($featureSlugs as $featureSlug) {
        $q->orWhere('slug', $featureSlug);
    }
})->get();

CodePudding user response:

Try it in this way.

$featureSlugs = ['security', 'mobile-app', '2FA'];

$exchanges = Exchange::whereHas('features', function ($query) use ($featureSlugs) {
    $query->distinct()->whereIn('slug', $featureSlugs);
}, '=', count($featureSlugs))->get();

CodePudding user response:

You can do this way:

$featureSlugs = ['security', 'mobile-app', '2FA'];

$exchanges = Exchange::whereHas('features', function ($q) use ($featureSlugs) {
                foreach($featureSlugs as $featureSlug)
                {
                    $q->where('slug', $featureSlug);
                }
            })-with(['features'=> function ($q) use ($featureSlugs) {
                foreach($featureSlugs as $featureSlug)
                {
                    $q->where('slug', $featureSlug);
                }
            }])->get();
  • Related