Laravel collection: return only relationship and key

5.3k Views Asked by At

I have a collection that resembles this:

$a = Model::with(['sub' => function($q) {
    $q->select('id', 'name')
}])->get();

This returns the following collection:

{
    0: {
        id: 0001,
        name: "item 1",
        type: "type a"
        'sub' [
            {
                'id': 10001,
                'name': "sub Item 1"
            },
            {
                'id': 10002,
                'name': "sub Item 2"
            }
        ]
    },
    1: {
        id: 0002,
        name: "item 2",
        type: "type a"
        'sub' [
            {
                'id': 11001,
                'name': "sub Item 4"
            },
            {
                'id': 11002,
                'name': "sub Item 5"
            }
        ]
    }

What I am trying to do is key the parent items by their ids and only return the relationship. For example

{
    0001: {
        'sub' [
            {
                'id': 10001,
                'name': "sub Item 1"
            },
            {
                'id': 10002,
                'name': "sub Item 2"
            }
        ]
    },
    0002: {
        'sub' [
            {
                'id': 11001,
                'name': "sub Item 4"
            },
            {
                'id': 11002,
                'name': "sub Item 5"
            }
        ]
    }

I cannot seem to get this to work. I have tried many variations including:

$a = Model::with(['sub' => function($q) {
    $q->select('id', 'name')
}])->pluck('sub', 'id');

This doesn't work as 'Pluck' is obviously looking for a a property of the parent model with the name of 'sub' which doesn't exit. Is there a way to achieve this?

2

There are 2 best solutions below

2
On BEST ANSWER

You were almost there. You will need to do ->get() before the pluck().

$a = Model::with([
    'sub' => function ($q) {
        $q->select('id', 'name');
    },
])->get()->pluck('sub', 'id');

The pluck() used in your example will be the query builder version of pluck rather than the collection version.

0
On

use keyBy to use your pk as array index. https://laravel.com/docs/5.4/collections#method-keyby

However ignoring other fields you probably would need each and filter. Wouldn't it be easier to select Sub::where(...) and then use collection groupBy on the parent_id: https://laravel.com/docs/5.4/collections#method-groupby

So something like Sub::where(...)->get()->groupBy('parent_id')