Laravel跨表插入数据报错:product_id字段不可为null
解决MySQL 1048错误:Column 'product_id' cannot be null
你遇到的这个问题是典型的Laravel模型主键字段不匹配导致的,我来一步步拆解原因和解决办法:
问题重现
当你尝试将products表的ID插入product_details表时,触发了MySQL的1048错误:
Column 'product_id' cannot be null
对应的执行SQL也能直接看出问题:
insert into product_details ( product_id , category , brand , provider_id ) values (, Peripherals, Riders, 1)
product_id的位置是空值,这就是报错的直接原因。
相关代码与配置
先梳理下你用到的代码和数据库结构:
业务逻辑代码
$product = Product::create([ 'product_name' => $request['product_name'], 'quantity' => $request['quantity'] ]); $product->save(); $product_id = $product->id; $productDetails = ProductDetails::create([ 'product_id' => $product_id, 'category' => $request['category'], 'brand' => $request['brand'], 'provider_id' => $request['provider_id'] ]);
ProductDetails模型的可填充字段
protected $fillable = ['product_id', 'category', 'brand', 'provider_id'];
数据库表结构
products表
Schema::create('products', function (Blueprint $table) { $table->increments('product_id'); $table->string('product_name'); $table->integer('quantity'); });
product_details表
Schema::create('product_details', function (Blueprint $table) { $table->integer('product_id')->unsigned(); $table->string('category',255); $table->string('brand',255); $table->integer('provider_id')->unsigned(); $table->foreign('product_id') ->references('product_id') ->on('products') ->onDelete('cascade'); $table->timestamps(); });
问题根源
Laravel的Eloquent模型默认会把id作为主键字段,但你的products表主键是product_id,不是框架默认的id。所以当你调用$product->id时,模型找不到对应的字段,返回的是null,这就导致插入product_details时product_id为空,触发了数据库的非空约束错误。
解决方案
有两种灵活的解决办法:
方法1:直接使用实际主键字段取值
修改业务代码中获取ID的部分,把$product->id改成$product->product_id即可:
$product = Product::create([ 'product_name' => $request['product_name'], 'quantity' => $request['quantity'] ]); // 补充个小优化:create()方法已经会自动保存记录到数据库,不需要额外调用save() $product_id = $product->product_id; // 这里改为实际主键字段名 $productDetails = ProductDetails::create([ 'product_id' => $product_id, 'category' => $request['category'], 'brand' => $request['brand'], 'provider_id' => $request['provider_id'] ]);
方法2:在Product模型中指定主键字段
如果你希望后续代码能继续使用$product->id的写法,可以在Product模型里显式声明主键字段:
class Product extends Model { protected $primaryKey = 'product_id'; // 添加这一行指定主键 }
这样设置后,Laravel会把product_id当作模型的主键,$product->id就会自动映射到product_id字段的值,不需要修改业务代码。
内容的提问来源于stack exchange,提问作者Nik
相关产品推荐
相关产品推荐

