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

Zygfried's avatar

Eloquent with hasMany relationship to single column strings array

Hi guys! I'm finishing a mobile app and providing an API through Laravel, everything is awesome but I struggle with one little problem. I have 3 entities: A Theme has many Items and a Theme belongs to a Language. I'm requesting my database with this inside my controller's action:

return Theme::whereHas('language', function ($query) use ($abbreviation) {
            $query->where('abbreviation', '=', $abbreviation);
        })->with(['items' => function ($query) {
            $query->get()->pluck('item')->toArray();
        }])->get();

Even with the pluck method, my API still returns an array of objects:

[
    {
            "id": 5,
            [...]
            "items": [
            {
                "item": "item 1..."
            },
            {
                "item": "item 2..."
            }
        ]
    }
]

I would like to transform the array into a strings array :

"items": [
"item 1", "item 2"
]

Am I doing it the wrong way? Thanks :)

0 likes
7 replies
Zygfried's avatar

Thanks Vilfago, we are half the way:

return Theme::whereHas('language', function ($query) use ($abbreviation) {
            $query->where('abbreviation', '=', $abbreviation);
        })->with(['items' => function ($query) {
            $query->get()->flatten()->all();
        }])->get();

When I debug it inside the closure, it provides the strings array but when I call the controller with my browser, nothing changes... It seems it doesn't affect the Eloquent request.

Vilfago's avatar

Maybe because you flattened to early.

Try :

return Theme::whereHas('language', function ($query) use ($abbreviation) {
            $query->where('abbreviation', '=', $abbreviation);
        })->with('items')
    ->get()->flatten();
1 like
Vilfago's avatar

Same result ? Or it didn't flatten at all ?

1 like
Zygfried's avatar

I've finally succeeded:

    /**
     * Show all themes from a specific language
     *
     * @param Language $language
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function show(string $abbreviation)
    {
        return Theme::whereHas('language', function ($query) use ($abbreviation) {
            $query->where('abbreviation', '=', $abbreviation);
        })->get()->map(function ($theme) {
           $theme['items'] = $theme->items()->get()->pluck('item')->all();
           return $theme;
        })->all();
    }

1 like

Please or to participate in this conversation.