Search code examples
phplaravellaravel-7

Constraint error when updating m2m relationship


I have a M2M relationship with a junction table, set up in the models as:

public function users()
{
    return $this->belongsToMany(User::class, 'user_alert', 'alert_id', 'user_id');
}

public function alerts()
{
    return $this->belongsToMany(Alert::class, 'user_alert', 'user_id', 'alert_id');
}

When editing an alert with this line, I get the following error.

Alert::findOrFail($request->id)->users()->syncWithoutDetaching($users);
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homestead`.`user_alert`, CONSTRAINT `user_alert_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE) (SQL: insert into `user_alert` (`alert_id`, `id`, `user_id`) values (43, 1, 0))

The user_id argument 0 is causing the error and I have no idea where it's coming from. Doing a dd($users) shows something similar to:

array:5 [
    0 => array:1 [
        "id" => 1
    ]
    1 => array:1 [
        "id" => 1
    ]
    2 => array:1 [
        "id" => 2
    ]
]

The 0 first appears in a call to /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php

    "file" => "/var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php"
    "line" => 254
    "function" => "insert"
    "class" => "Illuminate\Database\Query\Builder"
    "type" => "->"
    "args" => array:1 [▼
      0 => & array:1 [▼
        0 => array:3 [▼
          "alert_id" => 43
          "id" => 1
          "user_id" => 0
        ]
      ]
    ]
  ]

Frustratingly, the M2M relationship works when creating a new alert.

I hope it's not too relevant, but this is Laravel 7.

Hope somebody has some advice!


Solution

  • Problem is in the format of the $users data. syncWithoutDetaching can take collection of User models or array of user ids. Format you provided is not supported because takes array keys (0,1,2 in your example) as user ids.

    So please provide syncWithoutDetaching with collection of User models or array of user ids.