简体   繁体   English

Laravel 5.6保存测验记录时违反口才完整性约束

[英]Laravel 5.6 Eloquent integrity constraint violation when saving quiz record

I'm currently working on a quiz application with Laravel 5.6 and am having trouble with saving a new quiz record. 我目前正在使用Laravel 5.6开发测验应用程序,并且在保存新测验记录时遇到了麻烦。

The two tables that are being inserted into are quizzes and user_quizzes . 插入的两个表是quizzesuser_quizzes The quizzes table contains some basic quiz data such as: quizzes表包含一些基本测验数据,例如:

  • quiz_name quiz_name
  • quiz_description quiz_description
  • quiz_pin quiz_pin
  • active 活性

The user_quizzes table contains two foreign keys to reference which quiz belongs to a particular user. user_quizzes表包含两个外键,以引用哪个测验属于特定用户。

  • user_id 用户身份
  • quiz_id quiz_id

The error is an integrity constraint violation when inserting into the user_quizzes table. 当插入到user_quizzes表中时,该错误是违反完整性约束的。 It successfully inserts the quiz_id but the user_id is left as NULL. 它成功插入quiz_iduser_id保留为NULL。 I am unsure how to ensure the user_id is also inserted as I'm using Eloquent. 我不确定如何确保在使用Eloquent时也插入了user_id

The full error is: 完整的错误是:

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

I am making use of the QuizController , Quiz Model and User Model for saving the record. 我正在使用QuizControllerQuiz ModelUser Model来保存记录。 Here is my store() method in the QuizController : 这是我在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');

    }

My User Model is a follows: 我的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');
    }
}

and my Quiz model: 和我的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');
    }
}

Any guidance as to what I'm doing wrong would be greatly appreciated. 关于我在做什么错的任何指导将不胜感激。

Reviewing your code 查看您的代码

This is your controller: 这是您的控制器:

QuizController.php 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');
}

Now, the problem here is related to the $user object. 现在,这里的问题与$user对象有关。

When you do this: 执行此操作时:

$user = new User;

You are createing an instance of the User class, but this object isn't persisted yet into the database, what this means is that this object doens't have an id yet. 您正在创建User类的实例,但是该对象尚未持久保存到数据库中,这意味着该对象还没有id You can confirm this doing dd($user->id) , this will return null . 您可以通过dd($user->id)来确认,这将返回null

That's why when you do this: 这就是为什么当您这样做时:

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

It throws the SQL error, because you are calling a method to store the $primaryKey ( id ) of the $user object in the pivot table. 它将引发SQL错误,因为您正在调用将$user对象的$primaryKeyid )存储在数据透视表中的方法。 But given that the $user object doens't have a primary key is trying to store a null value instead. 但是考虑到$user对象没有主键,它试图存储一个null值。

Solution

Now, I don't really know what is your "use case", but I will assume that the $user is the logged-in one, so to relate properly the relationship replace this: 现在,我真的不知道您的“用例”是什么,但我将假定$user是已登录的$user ,因此要正确关联该关系,请替换为:

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

with this: 有了这个:

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

This will use the auth facade to get the actual logged-in user and return the object. 这将使用authfacade获取实际的登录用户并返回对象。 Given that is a registered user it will have a proper id . 鉴于该用户是注册用户,因此将具有正确的id

Alternative 替代

If your use case is different and you will relate the quiz to a different user, do this instead: 如果您的用例不同,则将测验与其他用户相关联,请执行以下操作:

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

or this, to create a completely new User instance and relating a quiz to it: 或创建一个全新的User实例并将测验与之关联:

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

Now you can attach the related model to it. 现在,您可以将相关模型附加到它。


Side note 边注

Your users m--------m quizzes is a many to many relationship . 您的users m--------m quizzes多对多关系

So, as the documentation says , the proper way to store a relatioship between the two objects is the attach() method: 因此,如文档所述,在两个对象之间存储关系的正确方法是attach()方法:

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

This method will create a record in the intermediate table (pivot) with the ids of the $user and $quiz objects. 此方法将使用$user$quiz对象的ID在中间表(数据透视表)中创建一条记录。

To make it clear, new User will only create user model object, it is still not committed to DB. 为了明确起见, new User将仅创建用户模型对象,但仍未提交给DB。

When we try to call $user->quizzes()->save($quiz) it is will try to add an entry in user_quizzes pivot table, but user_id is empty, because user is still not created. 当我们尝试调用$user->quizzes()->save($quiz) ,它将尝试在user_quizzes数据透视表中添加一个条目,但是user_id为空,因为仍未创建用户。

So you have to create a user entry in DB by calling $user->save() before adding it to pivot table. 因此,必须先在数据库中通过调用$user->save()创建用户条目,然后才能将其添加到数据透视表中。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM