Laravel 播种机不会用前键填满桌子

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

我正在开发一个 Laravel 项目,并且有以下迁移:

public function up(): void
{
    Schema::create('customers', function (Blueprint $table) {
        $table->id('customer_id');
        $table->string('first_name', 50);
        $table->string('last_name', 50);
        $table->string('address', 100)->nullable();
        $table->string('phone', 15)->nullable();
        $table->string('email', 50)->unique();
        $table->timestamp('registration_date')->default(DB::raw('CURRENT_TIMESTAMP'));
        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 */
public function down(): void
{
    Schema::dropIfExists('customers');
}
public function up(): void
{
    Schema::create('vehicles', function (Blueprint $table) {
        $table->id('vehicle_id');
        $table->foreignId('customer_id')->constrained('customers')->onDelete('cascade');
        $table->string('make', 50);
        $table->string('model', 50);
        $table->year('year');
        $table->string('license_plate', 15)->unique();
        $table->string('vin', 17)->unique();
        $table->string('color', 20)->nullable();
        $table->timestamp('registration_date')->default(DB::raw('CURRENT_TIMESTAMP'));
        $table->timestamps();
    });
}

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

正如您在

vehicles
表中看到的,有一个外键引用
customers
表。我将向您展示模型中的关系:

class Vehicle extends Model
{
    use HasFactory;

    /**
     * The primary key associated with the table.
     *
     * @var string
     */
    protected $primaryKey = 'vehicle_id';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'customer_id',
        'make',
        'model',
        'year',
        'license_plate',
        'vin',
        'color',
        'registration_date',
    ];

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class, 'customer_id');
    }
}
class Customer extends Model
{
    use HasFactory;

    /**
     * The primary key associated with the table.
     *
     * @var string
     */
    protected $primaryKey = 'customer_id';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'first_name',
        'last_name',
        'address',
        'phone',
        'email',
        'registration_date',
    ];

    public function vehicles(): HasMany
    {
        return $this->hasMany(Vehicle::class, 'customer_id');
    }
}

最后,工厂:

class CustomerFactory extends Factory
{
    protected $model = Customer::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'first_name' => fake()->name(),
            'last_name' => fake()->lastName(),
            'address' => fake()->address(),
            'phone' => fake()->phoneNumber(),
            'email' => fake()->email(),
            'registration_date' => fake()->date(),
        ];
    }
}

class VehicleFactory extends Factory
{
    protected $model = Vehicle::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'customer_id' => Customer::factory(),
            'make' => fake()->company,
            'model' => fake()->word,
            'year' => fake()->year,
            'license_plate' => strtoupper(fake()->unique()->bothify('???-####')),
            'vin' => strtoupper(fake()->unique()->bothify('?????????????????')),
            'color' => fake()->safeColorName,
            'registration_date' => fake()->date(),
        ];
    }
}

显然,发生了以下错误:

SQLSTATE[HY000]: General error: 1 foreign key mismatch - "vehicles" referencing "customers" (Connection: sqlite, SQL: insert into "vehicles" ("customer_id", "make", "model", "year", "license_plate", "vin", "color", "registration_date", "updated_at", "created_at") values (11, Wilderman Group, nostrum, 1970, VRF-4423, FVKRDKQWQHGDVFWBP, purple, 2019-01-16, 2024-11-13 18:30:33, 2024-11-13 18:30:33))

此错误是由于尝试在

vehicles
表中为 ID 为 11 的客户添加外键,而该外键显然不存在,因为只为 15 辆车创建了 10 个客户。我尝试通过循环所有创建的车辆并将它们分配给现有客户来“强制”错误消失,但这导致了另一个错误。我认为这里可能存在问题,修复起来比尝试以框架未设计的方式解决它要简单得多。如果有人知道可能出了什么问题,我将不胜感激。

附注我正在使用 Laravel 11

php laravel sqlite
1个回答
0
投票

我在之前的项目中这样做过并且有效。我会更正您的代码并向您展示。这几乎是正确的。尝试一下。

public function up(): void
{
 Schema::create('vehicles', function (Blueprint $table){
    $table->id('vehicle_id');
    $table->unsignedBigInteger('customer_id');
    $table->foreign('customer_id')->references('customer_id')->on('customers')->onDelete('cascade');
    $table->string('make', 50);
    $table->string('model', 50);
    $table->year('year');
    $table->string('license_plate', 15)->unique();
    $table->string('vin', 17)->unique();
    $table->string('color', 20)->nullable();
    $table->timestamp('registration_date')->default(DB::raw('CURRENT_TIMESTAMP'));
    $table->timestamps();
  }
}

现在您可以运行迁移了

php artisan migrate:fresh --seed
© www.soinside.com 2019 - 2024. All rights reserved.