保存测验记录时Laravel 5.6 Eloquent完整性约束违规

时间:2018-03-05 14:48:20

标签: php mysql laravel eloquent

我目前正在使用Laravel 5.6进行测验申请,但在保存新的测验记录时遇到了问题。

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

  • quiz_name
  • quiz_description
  • quiz_pin
  • 活性

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

  • USER_ID
  • quiz_id

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

完整错误是:

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来保存记录。以下是store()中的QuizController方法:

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

非常感谢任何关于我做错事的指导。

2 个答案:

答案 0 :(得分: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->id)确认这一点,这将返回null

这就是你这样做的原因:

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

它会抛出SQL错误,因为您正在调用一个方法来存储数据透视表中$primaryKey对象的id$user)。但是,如果$user对象没有主键,则会尝试存储null值。

解决方案

现在,我真的不知道你的用例是什么&#34;但是我会假设$user是登录的,所以要正确地联系这种关系替换这个:

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

用这个:

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

这将使用auth facade获取实际登录用户并返回该对象。鉴于这是注册用户,它将具有适当的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);

此方法将使用$user$quiz对象的ID在中间表(数据透视)中创建记录。

答案 1 :(得分:0)

为清楚起见,new User只会创建用户模型对象,但仍未提交给DB。

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

因此,在将数据库添加到数据透视表之前,必须先调用$user->save()在数据库中创建用户条目。

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