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

princelionelnzi's avatar

Find items using Laravel ORM

I am having two tables in my database presented as follow.

offers

ref_id
name

features

id
offer_id
name

What I am trying to do is to retrieve the various offers, for a given set of features. So I try using the following code but I am not getting the results expected:

$offers = Feature::find(['1', '2', '3'])->offers;

For instance:features with the id of 1 and 2 belongs to offer 1.

feature 3 belongs to offer 3.

From the code above, I am want $offers to contain only two elements offer 1 and 2

I try using the code below but the offers are duplicated:

$offers = DB::table('features')
            ->whereIn('features.id', ['1', '2', '3'])
            ->join('offers', 'offers.id', '=', 'features.offer_id')
            ->get();

kindly help me solve the problem.

0 likes
8 replies
davidfaux's avatar

You'd need to access the offers relationship within a loop:

$offers = [];

$features = Feature::find(['1', '2', '3']);

foreach($features as $feature) {
    $offers[] = $feature->offer;
}

dd($offers);

Though quite simplified here you can extrapolate to meet your requirements

princelionelnzi's avatar

@davidfaux Thanks for your reply. It helps me to build the following code.

        $offers = [];

        $features = Feature::find(['1', '2', '3', '4', '5']);

        foreach($features as $feature) {
            $offers[$feature->offer_id] = $feature->offer;
        }

        dd($offers);

Hope it can be improved ;)!

harran's avatar

@princelionelnzi try this

$featuresIds = [1, 2, 3, 4, 5]

$offers= Offer::whereHas('features', function ($query) use ($featuresIds) {
                    foreach ($featuresIds as $key => $featuresId) {
                        $query->where('id', $featuresId  );
                    }
                })->get();
davidfaux's avatar
Level 7

@princelionelnzi just make sure you prevent n+1 loading issues, the longer your featureId array gets the more database requests will occur which, in time, will slow down your application. My example above updated to account for this potential issue:

$offers = [];

$features = Feature::whereIn('id', ['1', '2', '3', '4', '5'])->with('offers')->get();

foreach($features as $feature) {
    $offers[] = $feature->offer;
}

dd($offers);

This update ends up performing 2 database requests, 1 to get the features and the other to get offers linked to the features. Without the with eager loading the code would interrogate the database 6 times, 1 to get the features and then once per foreach iteration to get the linked offers.

1 like
princelionelnzi's avatar

@dadidfaux thanks. You just saved me. BUt I made the the foreach looks like this:

foreach($features as $feature) {
      $offers[$feature->offer_id] = $feature->offer;
}

To avoid duplication of offers. Hope my method is good

davidfaux's avatar

If you're getting the output you required without making too many database queries your method is good.

Rather code at the level you can initially understand and once your skills increase you can refactor accordingly.

1 like

Please or to participate in this conversation.