Eloquent一对多模型存储问题:transaction_id无默认值报错
解决
Field 'transaction_id' doesn't have a default value报错问题 这个错误的核心原因很明确:当你调用$user->orders()->save($order)的时候,Laravel会立即把这条Order记录插入到数据库,但此时transaction_id字段没有被赋值,而你的数据库迁移里这个字段既没有设置默认值,也没有允许为空,所以数据库直接抛出了这个错误。
而且你后续调用的$transaction->orders()->save($order)其实是多余的——因为第一次save已经把Order写入数据库了,这时候再执行这个操作只会尝试重复保存,反而会引发其他问题。
下面给你几个可行的解决办法:
方法一:创建Order时直接赋值transaction_id
在保存Order之前,直接把transaction的ID赋值给Order的对应字段,然后一次性保存:
$user->save(); $transaction->save(); $order = new Order(); $order->user_id = $user->id; $order->transaction_id = $transaction->id; // 直接关联transaction $order->save(); $order->products()->attach($cartItem->id, ['quantity' => $cartItem->qty]);
方法二:使用关联的create方法一次性创建并关联
利用Laravel关联的create方法,在创建Order的同时传入transaction_id,代码更简洁:
$user->save(); $transaction->save(); // 通过user的orders关联创建Order,同时传入transaction_id $order = $user->orders()->create([ 'transaction_id' => $transaction->id ]); $order->products()->attach($cartItem->id, ['quantity' => $cartItem->qty]);
方法三:允许transaction_id为空(仅适合非必填场景)
如果你的业务逻辑允许Order暂时不关联Transaction,可以修改orders表的迁移,让transaction_id字段允许为空:
Schema::create('orders', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned()->index()->nullable(); $table->foreign('user_id')->references('id')->on('users'); $table->integer('transaction_id')->unsigned()->nullable(); // 添加nullable() $table->foreign('transaction_id')->references('id')->on('transactions'); $table->timestamps(); });
修改后需要重新执行迁移,不过这个方法只适合业务上允许Order无Transaction的情况,如果你要求每个Order必须属于一个Transaction,优先选前两种方法。
额外提醒:修正迁移代码结构
你的迁移代码里把order_product、products、transactions的创建都嵌套在了orders的闭包里面,这是错误的!这些表的创建应该单独写在各自的Schema::create闭包里,不然会导致迁移执行失败。正确的迁移结构应该是:
Schema::create('orders', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned()->index()->nullable(); $table->foreign('user_id')->references('id')->on('users'); $table->integer('transaction_id')->unsigned(); $table->foreign('transaction_id')->references('id')->on('transactions'); $table->timestamps(); }); Schema::create('order_product', function (Blueprint $table) { $table->integer('order_id')->unsigned()->index(); $table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade'); $table->integer('product_id')->unsigned()->index(); $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); $table->integer('quantity')->unsigned(); $table->timestamps(); }); Schema::create('products', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->float('price',8,2); $table->timestamps(); }); Schema::create('transactions', function (Blueprint $table) { $table->increments('id'); $table->enum('status',['open','closed']); $table->timestamps(); });
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

