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

vincent15000's avatar

Query with() retrieving only an array of ids from the relationship

Hello,

I have a many-to-many relationship and I'd like to retrieve the items of the relationship like this.

$trainer = Trainer::with(['skills' => function($query) {
    $query->select('id');
}])->find($id);

I retrieve this ...

"skills":[{"id":1,"pivot":{"trainer_id":8,"skill_id":1}},{"id":9,"pivot":{"trainer_id":8,"skill_id":9}},{"id":10,"pivot":{"trainer_id":8,"skill_id":10}}]

... but I'd like to retrieve only an array of the skills ids.

"skills":[1, 9, 10]

I know how to retrieve this with another distinct query, but is it possible to get what I want using a query like this one above ?

Thanks for your help ;).

V

0 likes
9 replies
jlrdw's avatar

You can try pluck, to get just skill_id.

vincent15000's avatar

Thank you @jlrdw ... well ... ok ... I want to retrieve all the fields for the trainer but only the id for the skills.

I have tried with pluck but with pluck I retrieve all fields from the pivot table.

vincent15000's avatar

Wow ... here is something but it's not yet the solution, it approaches.

        $trainer = Trainer::with('skills')->find($id);
        return $trainer->skills->pluck('id');

I retrieve only the array of ids.

I'd like the same with all the fields of the trainer.

jlrdw's avatar

Something like this in your case, I don't use pluck often.

$trainer = Trainer::with('skills')->get()->pluck('skills.skill_id');

or try

$trainer = Trainer::with('skills')->get()->pluck('skill_id');

Edit can also try:

Trainer::with(['skills' => function($query) { $query->select('skill_id'); }])->get()

And if you need array, just convert or map.

2 likes
vincent15000's avatar

Hello thank you ... I had already tried this but doing this I retrieve the pivot datas too, which I don't need.

Snapey's avatar

in a single line?

    return Trainer::find($id)->skills()->pluck('id')->toArray();

or

    return Trainer::find($id)->skills->keys();

edit: Sorry you said you wanted all the trainer fields as well. You will have to add them back into the model under a different key

$trainer = Trainer::find($id);
$trainer->skillkeys = $trainer->skills->keys();
return $trainer;

But I don't really know why you need to reduce to just the keys at this stage. Why not do the reduction when you come to use the keys.

vincent15000's avatar

Well ... to answer to your question, I want to display the skills with checkboxes.

So I need to retrieve the entire list of skills (from the Skill model) and to retrieve the selected skills for a specific trainer. Then when displaying the skills, I test if the skill id is in the skillIds in the pivot table.

Something like this in VueJS.

this.skills.forEach(
	skill => {
		if (this.trainer.skillIds.includes(skill.id)) {
			skill.checked = true
		}
	}
)

With my view.

<b-checkbox
	v-model="skill.checked">
</b-checkbox>

If you have another idea to do the same, why not ;).

I had already tried your proposition with adding the skillIds into the model under a different key, but doing so I retrieve the entire pivot datas too and I don't understand why. That's not a problem to do my code working, but I'd like to retrieve only what I really need. I think the problem is that I don't understand why and I really want know how to solve this ;).

Snapey's avatar

if you are sending models to javascript then perhaps you should be looking at responsable classes?

Snapey's avatar
Snapey
Best Answer
Level 122

This way won't have the pivot data

$trainer = Trainer::find($id);
$trainer->skillkeys = $trainer->skills()->pluck('id')->toArray();
return $trainer;

Please or to participate in this conversation.