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

kazehaya's avatar

Sync three way pivot

Hey guys,

Im wondering how i can get my sync working with when using a three way pivot table.

What i have tried so far is:

public function projects()
    {
        return $this->belongsToMany('App\Project', 'project_user', 'user_id', 'project_id')->withPivot('role_id');
    }

Use the sync method:

$user->projects()->sync($projects, array('role_id' => $roles));

But this is not updating my role_id field inside the pivot table.

I have no idea what i do wrong here and hope someone can explain to me how to get this working.

0 likes
6 replies
pmall's avatar

A three way pivot is hell.

In this situation try to introduce another model to get back to classic two sided relationship. Here try to add a model representig the couple User/Project, which has a classic hasMany relationship with Role.

JarekTkaczyk's avatar
Level 53

@kazehaya You're doing it wrong ;)

$user->projects()->sync([
   1 => ['role_id' => $roles],
   4 => ['role_id' => $roles],
   9 => ['role_id' => $roles],
]);

This is how sync works when you want to update existing rows (as well as insert new ones). 1, 4 and 9 are projects ids, so just build an array that looks like this.

For triple pivot you can use this https://github.com/jarektkaczyk/Eloquent-triple-pivot/ , however mind that it is not complete and I'm not working on it anymore.

kazehaya's avatar

@JarekTkaczyk Thanks for helping me on the right pad! I think i have come up with a solution, just need to get the key of the projects:)

this is what i have done:

        $syncArray = array_build($roles, function ($key, $value) {
            return [$key, ['role_id' => $value]];
        });

This is what i get in return:

array:2 [▼
  0 => array:1 [▼
    "role_id" => "5"
  ]
  1 => array:1 [▼
    "role_id" => "1"
  ]
]

Do you want to help me so the keys above match to that of the project id's? :)

kazehaya's avatar

@JarekTkaczyk I came up with a solution myself!

What do you think of this? ;)

        $syncArray = [];
        foreach($projects as $project_id) {
            $syncArray += array_build($roles, function ($project_id, $value) use ($project_id) {
                return [$project_id, ['role_id' => $value]];
            });
        }

kazehaya's avatar

@JarekTkaczyk Thanks so much!!

This is how i get it working!

        $data = array_build($roles, function ($key, $value) {
            return [$key, ['role_id' => $value]];
        });

        $syncArray = array_combine($projects, $data);

        $user->projects()->sync($syncArray);

Again big thanks for helping me and sharing your knowledge, it means a lot to me and i think to others here on the forum as well!

Please or to participate in this conversation.