You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Backpack for Laravel创建产品时报1364错误:produit_type_id无默认值

问题:Backpack for Laravel 创建产品时 produit_type_id 未提交导致数据库错误

Illuminate\Database\QueryException
PHP 8.2.0
10.23.1
SQLSTATE[HY000]: General error: 1364 Field 'produit_type_id' doesn't have a default value
INSERT INTO produits (nom, description, quantite, updated_at, created_at) VALUES (TEtrdesfddfsdf, dsfdfsdf, 10, 2023-09-26 14:39:57, 2023-09-26 14:39:57)

即使设置了$fillable或$guarded = [],请求中仍未携带produit_type_id字段,仅手动填写ID(比如用select_from_array)时才能正常工作。数据库中该字段不允许为NULL,需要排查字段未正确提交的原因。


提供的代码文件

迁移文件

produits表迁移

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('produits', function (Blueprint $table) {
            $table->id();
            $table->string('nom')->nullable(false);
            $table->string('quantite')->default(0);
            $table->longText('description')->nullable();
            $table->unsignedBigInteger('produit_type_id')->nullable(false);
            $table->foreign('produit_type_id')->references('id')->on('produit_types');
            $table->timestamps();
        });
    }

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

produit_types表迁移

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('produit_types', function (Blueprint $table) {
            $table->id();
            $table->string('nom')->nullable(false);
            $table->timestamps();
        });
    }

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

模型文件

Produits模型

<?php

namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Produits extends Model
{
    use CrudTrait;
    use HasFactory;

    protected $guarded = [];

    protected $table = 'produits';

    public function produitType(): HasOne
    {
        return $this->hasOne(ProduitTypes::class, 'id', 'produit_type_id');
    }
}

ProduitTypes模型

<?php

namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class ProduitTypes extends Model
{
    use CrudTrait;
    use HasFactory;

    protected $guarded = [];

    protected $table = 'produit_types';

    public function produits(): BelongsToMany
    {
        return $this->belongsToMany(Produits::class);
    }
}

CRUD控制器

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Requests\ProduitsRequest;
use App\Models\ProduitTypes;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;

/**
 * Class ProduitsCrudController
 * @package App\Http\Controllers\Admin
 * @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
 */
class ProduitsCrudController extends CrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;

    /**
     * Configure the CrudPanel object. Apply settings to all operations.
     *
     * @return void
     */
    public function setup()
    {
        CRUD::setModel(\App\Models\Produits::class);
        CRUD::setRoute(config('backpack.base.route_prefix') . '/produits');
        CRUD::setEntityNameStrings('produit', 'produits');
    }

    /**
     * Define what happens when the List operation is loaded.
     *
     * @see  https://backpackforlaravel.com/docs/crud-operation-list-entries
     * @return void
     */
    protected function setupListOperation()
    {
        CRUD::setFromDb(); // set columns from db columns.

        /**
         * Columns can be defined using the fluent syntax:
         * - CRUD::column('price')->type('number');
         */
    }

    /**
     * Define what happens when the Create operation is loaded.
     *
     * @see https://backpackforlaravel.com/docs/crud-operation-create
     * @return void
     */
    protected function setupCreateOperation()
    {
        $this->crud->addField([
            'name' => 'nom',
            'label' => 'Nom',
            'type' => 'text',
            'placeholder' => 'Nom du produit',
            'validationRules' => 'required|min:3'
        ]);

        $this->crud->addField([
            'label' => 'Type de produit',
            'type' => 'select',
            'name' => 'produit_type_id',
            'entity' => 'produitType',
            'attribute' => 'nom',
            'model' => "App\Models\ProduitTypes",
        ]);

        $this->crud->addField([
            'name' => 'description',
            'label' => 'Description',
            'type' => 'textarea',
            'placeholder' => 'Description du produit',
            'validationRules' => 'required'
        ]);

        $this->crud->addField([
            'name' => 'quantite',
            'label' => 'Quantité',
            'type' => 'number',
            'value' => '0',
            'validationRules' => 'required'
        ]);


    }

    /**
     * Define what happens when the Update operation is loaded.
     *
     * @see https://backpackforlaravel.com/docs/crud-operation-update
     * @return void
     */
    protected function setupUpdateOperation()
    {
        $this->setupCreateOperation();
    }
}

问题排查与修复步骤

1. 修正模型关联关系

模型关联定义错误会导致Backpack无法正确识别关联字段:

  • Produits模型:produitType 应为BelongsTo关联(产品属于一个类型),而非HasOne:
// 替换原produitType方法
public function produitType(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
    return $this->belongsTo(ProduitTypes::class, 'produit_type_id');
}
  • ProduitTypes模型:produits 应为HasMany关联(一个类型对应多个产品),而非BelongsToMany:
// 替换原produits方法
public function produits(): \Illuminate\Database\Eloquent\Relations\HasMany
{
    return $this->hasMany(Produits::class, 'produit_type_id');
}

2. 给CRUD的select字段添加必填验证

在setupCreateOperation的produit_type_id字段配置中添加验证规则,确保用户必须选择:

$this->crud->addField([
    'label' => 'Type de produit',
    'type' => 'select',
    'name' => 'produit_type_id',
    'entity' => 'produitType',
    'attribute' => 'nom',
    'model' => "App\Models\ProduitTypes",
    'validationRules' => 'required|exists:produit_types,id' // 添加此行
]);

3. 检查ProduitsRequest类

确保App\Http\Requests\ProduitsRequest中包含produit_type_id的验证规则,且授权逻辑正常:

public function rules()
{
    return [
        'nom' => 'required|min:3',
        'produit_type_id' => 'required|exists:produit_types,id',
        'description' => 'required',
        'quantite' => 'required|numeric'
    ];
}

public function authorize()
{
    return backpack_auth()->check();
}

4. 验证字段渲染

检查创建页面的HTML源码,确认produit_type_id的select元素存在且name属性正确。若字段未渲染,大概率是模型关联错误导致Backpack无法加载选项。


内容的提问来源于stack exchange,提问作者edouard dragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:32:03