【问题标题】:Laravel 5.6 Eloquent integrity constraint violation when saving quiz record保存测验记录时 Laravel 5.6 Eloquent 完整性约束违规
【发布时间】:2018-03-12 15:53:06
【问题描述】:

我目前正在使用 Laravel 5.6 开发一个测验应用程序,但无法保存新的测验记录。

要插入的两个表是quizzesuser_quizzesquizzes 表包含一些基本的测验数据,例如:

  • 测验名称
  • quiz_description
  • quiz_pin
  • 有效

user_quizzes 表包含两个外键,用于引用哪个测验属于特定用户。

  • user_id
  • quiz_id

错误是插入user_quizzes 表时违反完整性约束。它成功插入了quiz_id,但user_id 保留为NULL。我不确定如何确保 user_id 在我使用 Eloquent 时也被插入。

完整的错误是:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null (SQL: insert into `user_quizzes` (`quiz_id`, `user_id`) values (6, ))

我正在使用QuizControllerQuiz ModelUser Model 来保存记录。这是我在QuizController 中的store() 方法:

public function store(Request $request)
    {

        $validator = $request->validate([
            'quiz_name'        => 'required|max:30',
            'quiz_description' => 'required|max:500'
        ]);

        $quiz = new Quiz(
            [
                'quiz_name'        => $request->get('quiz_name'),
                'quiz_description' => $request->get('quiz_description'),
                'active'           => '0',
                'quiz_pin'         => '5555', // hard coded for now
            ]
        );

        $quiz->save();
        $user = new User;
        $user->quizzes()->save($quiz);

        return redirect()->route('quiz_host.dashboard.manage-quizzes')->with('quizCreated', 'Whoa ' . Auth::user()->username . ', you have created a quiz! Now it\'s time to add some questions');

    }

我的User 型号如下:

<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'username', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function activation()
    {
        return $this->hasOne('App\Models\Activation');
    }

    public function profile()
    {
        return $this->hasOne('App\Models\Profile');
    }

    public function quizzes()
    {
        return $this->belongsToMany(Quiz::class, 'user_quizzes', 'user_id', 'quiz_id');
    }
}

还有我的Quiz 模特:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Quiz extends Model
{
    protected $table = 'quizzes';
    protected $fillable = ['quiz_name', 'quiz_description', 'active', 'quiz_pin'];

    public function user()
    {
        return $this->belongsToMany(User::class, 'user_quizzes', 'quiz_id', 'user_id');
    }
}

任何关于我做错了什么的指导将不胜感激。

【问题讨论】:

  • 先创建用户,再附加测验。
  • 我很确定$quiz-&gt;save();$user-&gt;quizzes()-&gt;save($quiz); 都在数据库中插入了一条新记录;如果是这种情况,您只需省略第一个$quiz-&gt;save()。否则,请先保存您的User,然后将测验的user_id 设置为保存的用户,然后再调用$quiz-&gt;save();
  • 谢谢你们,我将当前用户设置为$user = Auth::user(),然后省略了$quiz-&gt;save(),然后离开$user-&gt;quizzes()-&gt;save($quiz),它现在可以工作了。

标签: php mysql laravel eloquent


【解决方案1】:

审查您的代码

这是你的控制器:

QuizController.php

public function store(Request $request)
{
    // your validations.

    // Storing the quiz.
    $quiz->save();

    // User instance.
    $user = new User;

    // Storing the relationship.
    $user->quizzes()->save($quiz);

    // Returning the view.
    return redirect()->route('quiz_host.dashboard.manage-quizzes')->with('quizCreated', 'Whoa ' . Auth::user()->username . ', you have created a quiz! Now it\'s time to add some questions');
}

现在,这里的问题与$user 对象有关。

当你这样做时:

$user = new User;

您正在创建User 类的实例,但该对象尚未持久化到数据库中,这意味着该对象还没有id。您可以通过dd($user-&gt;id) 确认此操作,这将返回null

这就是为什么当你这样做时:

$user->quizzes()->save($quiz);

它会引发 SQL 错误,因为您正在调用一个方法来将 $user 对象的 $primaryKey (id) 存储在数据透视表中。但鉴于 $user 对象没有主键,因此尝试存储 null 值。

解决方案

现在,我真的不知道您的“用例”是什么,但我会假设 $user 是已登录的,因此要正确关联关系,请替换此:

    // creating a User instance.
    $user = new User;

用这个:

    // Logged-in user.
    $user = auth()->user();

这将使用 auth 外观来获取实际登录的用户并返回对象。鉴于这是一个注册用户,它将有一个正确的id

另类

如果您的用例不同并且您将测验与不同的用户相关联,请改为:

    // Some other user
    $user = User::find($someId); // $user = User::find(5); for example

或者这样,创建一个全新的User 实例并与之相关的测验:

    // A new User
    $user = new User;
    $user->fill($someData);
    $user-save(); // this will assign a primary key (id) to the object.

现在您可以将相关模型附加到它。


旁注

您的users m--------m quizzesmany to many relationship

因此,作为the documentation says,存储两个对象之间关系的正确方法是attach() 方法:

    $user->quizzes()->attach($quiz->id);

此方法将在中间表(数据透视表)中创建一条记录,其 ID 为 $user$quiz 对象。

【讨论】:

    【解决方案2】:

    为了明确,new User 只会创建用户模型对象,它仍然没有提交给 DB。

    当我们尝试调用 $user-&gt;quizzes()-&gt;save($quiz) 时,它会尝试在 user_quizzes 数据透视表中添加一个条目,但 user_id 为空,因为尚未创建用户。

    因此,您必须先调用$user-&gt;save() 在数据库中创建一个用户条目,然后再将其添加到数据透视表。

        $quiz->save();
        $user = new User;
        $user->save();
        $user->quizzes()->save($quiz);
    

    【讨论】:

      猜你喜欢
      • 2020-04-22
      • 1970-01-01
      • 2015-05-07
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2019-07-22
      相关资源
      最近更新 更多