Home » Php » php – Trying to return pivot data in Resource Laravel

php – Trying to return pivot data in Resource Laravel

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am trying to return pivot data to a resource.
The pivot table works, I can add and remove entrys like expected, but I am not able to get the user_id returned in ActivityResource…
In the Laravel Documentation it looks so easy, am I missing something?

// Activity.php
class Activity extends Model
{
    public function members()
    {
        return $this->belongsToMany('App\User', 'activity_user', 'user_id', 'activity_id')->withPivot('activity_id','user_id')->withTimestamps();
    }
}
// User.php
class User extends Authenticatable
{
    public function joinedactivities()
    {
        return $this->belongsToMany('App\Activity');
    }
}

In my ActivityController I want to return a newly created ActivityResource with ‘eager-loaded’ relationship

// ActivityController 
public function show($id)
{
    $activity = Activity::with('members')->findOrFail($id);

    /* foreach ($activity->members as $user) {
        echo $user->id . " "; // With this I can actually see the right ids
    }
    return;*/

    return new ActivityResource($activity);
}

ActivityResource:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        'attendees' => $this->whenPivotLoaded('activity_user', function () {
            return $this->pivot->user_id;
        }),
    ];
}

I dont get any errors instead the attendees field is just not returned. I tried so many things, struggeling with that. Help very appreciated.
I am using Laravel 6.

How to&Answers:

->withPivot('activity_id','user_id') is not needed. Those fields will appear on your relation object no matter what. For the resource, I think you can do the following:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        // If the relation 'members' is loaded, get an array of user ids otherwise, return null
        'attendees' => $this->relationLoaded('members') ? $this->members->pluck('pivot.user_id')->unique()->all() : null
    ];
}

The main problem is the relationship is a Many to Many, meaning there’s more than 1 pivot. With this solution, your object will look like this.

{
    id: 3,
    title: 'A Title',
    attendees: [
        1,
        2,
        3,
    ],
}

If you want the ids concatenated in a single string like in your commented foreach, replace all() by join(' ')

// If the relation 'members' is loaded, get an string of user ids otherwise, return null
'attendees' => $this->relationLoaded('members') ? $this->members->pluck('pivot.user_id')->unique()->join(' ') : null
{
    id: 3,
    title: 'A Title',
    attendees: '1 2 3',
}