SpuriouslyAwake's avatar

Pluck from a nested collection?

Hi, I'm trying to pluck the strand_id value from the following collection

 Illuminate\Database\Eloquent\Collection {#3820
     all: [
       App\Activity {#3814
         id: 1,
         title: "Test activity number one",
         provider: "Some provider",
         description: "Here is a description",
         hours: "3.00",
         date: "2017-02-21",
         deleted_at: null,
         created_at: "2017-02-21 10:19:52",
         updated_at: "2017-02-21 10:19:52",
         pls: Illuminate\Database\Eloquent\Collection {#3827
           all: [
             App\ParticipantLevelStrand {#3829
               id: 1,
               participant_level_id: 1,
               strand_id: 1,
               pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3826
                 activity_id: 1,
                 pls_id: 1,
               },
             },
           ],
         },
       },

$collection->pluck('pls') works fine but when i'm trying to nest the query to $collection->pluck('pls.strand_id') I get null. Am I missing something obvious here?

0 likes
11 replies
cviv's avatar

did you try $collection->pluck('strand_id')?

kenny11's avatar

Because you are trying to access an array of objects like an object.

staudenmeir's avatar

Use this:

$collection->pluck('pls')->flatten()->pluck('strand_id')
10 likes
Francismori7's avatar
->map(function($item) { return $item->pls->pluck('strand_id'); });
3 likes
ctf0's avatar

@STAUDENMEIR - thank you so much, here is a macro with dynamic search

Collection::macro('pluckMulti', function ($field) {
    $arr = explode('.', $field);
    $toGet = array_pop($arr);

    $res = $this;
    foreach ($arr as $relation) {
        $res = $res->pluck($relation)->flatten();
    }

    return $res->pluck($toGet);
});
3 likes
timesheep's avatar

That's a cool solution, and I almost started to use it. But then I realized you can extend on @arctic-ice-cool's answer and do $collection->pluck('pls.*.strand_id');

In my particular case, I ended up with something like this:

$host_groups->each->service_groups->each->services->pluck('service_groups.*.services.*.name');
2 likes
meduz's avatar

In the nesting case I have, I used @timesheep’s solution followed by flatten().

For a data structure being:

(collection) $users -> (collection) $things -> property

I could get a collection of property with:

$users->pluck('things.*.property')->flatten();

2 likes

Please or to participate in this conversation.