为什么“set null”在 Laravel 9 的 onDelete 中不起作用? [重复]

问题描述 投票:0回答:2

我有一个Plan模型和一个User模型,User有一个计划,而该计划属于多个User;

当我运行

php artisan migrate:fresh
时,我收到此错误:

** SQLSTATE[HY000]:一般错误:1005无法创建表

service6_servicelandv1.0
users
(errno:150“外键约束格式不正确”)(SQL:alter table
users
添加约束
users_plan_id_foreign
外键(
plan_id
) 引用
plans
(
id
) 删除集 null) **

以下是迁移:

用户迁移

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string("avatar_name")->default("default-male.jpg");
            $table->string('username')->unique();
            $table->string("email")->unique();
            $table->string('password');
            $table->string("role")->default('Regular')->nullable();
            $table->string("address")->nullable();
            $table->bigInteger("reputation")->default(0);
            $table->string("phone_number")->nullable();
            $table->float("wallet", 10, 2)->default(0);
            $table->unsignedBigInteger("plan_id")->nullable();
            $table->unsignedBigInteger("option_id")->nullable();
            $table->unsignedBigInteger("category_id")->nullable();//fav_category
            
            $table->rememberToken();
            $table->timestamp('email_verified_at')->nullable();
            $table->timestamp("created_at")->useCurrent();
            $table->timestamp("updated_at")->useCurrent();

            $table->foreign("plan_id")->references("id")->on("plans")->onDelete('set null');
            $table->foreign("option_id")->references("id")->on("options")->onDelete('set null');
            $table->foreign("category_id")->references("id")->on("categories")->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};

对于计划迁移:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('plans', function (Blueprint $table) {
            $table->id("id");
            $table->string("name");
            $table->integer("ads_number");
            $table->decimal('amount_credit', 9, 3, true);
            $table->decimal('price', 9, 3, true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('plans');
    }
};

用户型号:

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
// use Laravel\Sanctum\HasApiTokens; // comment this
use Laravel\Passport\HasApiTokens; // include this

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        "avatar_name",
        'username',
        'email',
        'password',
        "address",
        "role", 
        "reputation", 
        "wallet",
        "phone_number",
        "plan_id",
        "option_id",
        "category_id",
        'confirmation_password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
    /**
     * Get the image url.
     *
     * @param  string  $value
     * @return string
     */
    public function getAvatarNameAttribute($value){
        return asset('storage/avatars/' . $value);
    }

    public function role(){
        return $this->hasOne(Role::class);
    }

    public function category(){
        return $this->hasOne(Category::class);
    }

    public function plan(){
        return $this->hasOne(Plan::class);
    }

    public function option(){
        return $this->hasOne(Option::class);
    }

    public function postStars(){
        return $this->hasManyThrough(PostStar::class, Post::class);
    }
}

计划型号:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Plan extends Model
{
    use HasFactory;

    protected $fillable=[
        "name",
        "ads_number",
        "amount_credit",
        "price"
    ];

    public function user(){
        return $this->belongsTo(User::class);
    }
}

拜托,我现在真的被困了大约两个小时,我不明白发生了什么??!这是怎么回事

set null
??

php laravel model relationship
2个回答
1
投票

在 Laravel 中你可以使用

nullOnDelete()

$table->foreignId('plan_id')
        ->nullable()
        ->constrained('plans')
        ->nullOnDelete();

浏览 Laravel 外键约束 以了解一些关于 外键 声明


0
投票

您可以简单地使用此方法来分配

foreign keys

$table->foreignId('user_id')
  ->nullable()
  ->constrained()
  ->onUpdate('cascade')
  ->onDelete('set null');

这比其他方法要好得多。

检查文档

© www.soinside.com 2019 - 2024. All rights reserved.