【问题标题】:Laravel integrity constraint violation when saving many to many relationship保存多对多关系时违反 Laravel 完整性约束
【发布时间】:2014-06-07 00:45:01
【问题描述】:

当存储一个新用户和 syncing 一些多对多关系时,我收到一个完整性约束错误,因为新创建的用户的 ID 似乎没有传递给 sync() 方法。这是我的store 控制器方法:

$user = new User;
$user->name = Input::get('name');
$user->username = Input::get('username');
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->save();

// See if roles are passed, if not assign the default role of "view_site"
$roles = Input::has('roles') ? Input::get('roles') : [3];
$user->roles()->sync($roles);

如您所见,我在尝试sync 相关数据之前调用了save(),因此它应该有一个ID。这是错误:

违反完整性约束:1048 列 'user_id' 不能为空 (SQL: 插入users_roles (role_id, user_id) 值 (3, ))

如果我在已经存在的用户 (User::find($id)->roles()->sync([1,2,3])) 上运行同步方法,它可以正常工作。

供参考,关系:

// User.php
public function roles()
{
    return $this->belongsToMany('Role', 'users_roles');
}
// Role.php
public function users()
{
    return $this->belongsToMany('User', 'users_roles');
}

编辑:

sync() 之前的查询日志。看起来save() 没有写入数据库...

Array
(
    [0] => Array
        (
            [query] => select * from `users` where `id` = ? limit 1
            [bindings] => Array
                (
                    [0] => 1
                )

            [time] => 0.63
        )

    [1] => Array
        (
            [query] => select `roles`.*, `users_roles`.`user_id` as `pivot_user_id`, `users_roles`.`role_id` as `pivot_role_id` from `roles` inner join `users_roles` on `roles`.`id` = `users_roles`.`role_id` where `users_roles`.`user_id` = ?
            [bindings] => Array
                (
                    [0] => 1
                )

            [time] => 0.58
        )

    [2] => Array
        (
            [query] => select count(*) as aggregate from `users` where `email` = ? or `username` = ?
            [bindings] => Array
                (
                    [0] => test@example.com
                    [1] => example
                )

            [time] => 0.48
        )

)

【问题讨论】:

  • 只是为了调试:如果你执行User::find($validId)->roles()->sync($roles);,你会得到同样的错误吗?
  • 不,完美运行
  • 也许您正在使用Ardent(保存时自动验证),所以当您调用$user->save(); 时没有任何反应。无论如何,请在最后添加var_dump('DB::getQueryLog()'),并分享结果
  • 我使用的是 confide,但不是 ardant。我会得到查询日志并在上面发布
  • 有道理,因为字段/模型验证由Ardent 提供支持,您有两个选择:重新检查您的验证,或使用->forceSave() 方法

标签: php laravel laravel-4


【解决方案1】:

由于您使用的是confide,因此验证基于Ardent。 在您的store 方法中,添加if 语句

if($user->save());
    $roles = Input::has('roles') ? Input::get('roles') : [3];
    $user->roles()->sync($roles);
}else{
    return Redirect::back()->withErrors($user->errors());
}

如果你不需要检查验证,你可以使用

$user->forceSave();

【讨论】:

  • 感谢您的建议。看来这是一个验证错误。无论如何,我在使用if ( Validator::make(Input::all(), User::$rules)->passes() ) 之前运行了验证器,它似乎通过了。但是,添加您的代码似乎确实存在密码确认不匹配的问题。我在表单中包含password_confirmation 输入。
  • 我是否也需要 $user->password_confirmation = Input::get('password_confirmation'); 才能让 Ardent 进行检查?
  • 看来你需要添加它。请出示您的$rules
  • 是的,我的规则确实包含confirmed 作为密码。正如你所说,这个问题很激烈。已经删除了正常的 laravel 验证,它现在可以正常工作了。谢谢。
猜你喜欢
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 2014-12-18
相关资源
最近更新 更多