Laravel Eloquent链式创建多模型记录问题求助
问题
我想使用Eloquent的链式创建方法一次性创建3条记录,现有代码如下:
$role = ($input['role'] == 'creator') ? 'creator' : 'sponsor'; $user->$role()->create([ 'plan_id' => 1, 'name' => $input['name'] ]);
但无法创建Creator或Sponsor记录,当前报错信息:
"SQLSTATE[HY000]: General error: 1364 Field 'plan_id' doesn't have a default value (SQL: insert into `creators` (`name`, `user_id`, `updated_at`, `created_at`) values (Juan, 1, 2023-02-22 11:18:21, 2023-02-22 11:18:21))"
原因是这两个表的plan_id字段关联account_plans表,请问能否先创建Plan再创建角色?
使用的三个模型代码如下:
class Sponsor extends Model { public function plans(){ return $this->hasOne(AccountPlan::class); } } class Creator extends Model { public function plans(){ return $this->hasOne(AccountPlan::class); } } class User extends Authenticatable implements MustVerifyEmail { public function sponsor() { return $this->hasOne(Sponsor::class); } public function creator() { return $this->hasOne(Creator::class); } }
解决方案
1. 修正模型可填充字段
报错SQL里未包含plan_id,是因为Creator和Sponsor模型没把该字段加入$fillable白名单,Eloquent会自动过滤白名单外的字段。给两个模型添加白名单:
class Sponsor extends Model { protected $fillable = ['name', 'plan_id']; // 按需补充其他需批量赋值的字段 // 其他代码... } class Creator extends Model { protected $fillable = ['name', 'plan_id']; // 按需补充其他需批量赋值的字段 // 其他代码... }
2. 修正关联关系逻辑
从表结构看,creators和sponsors表通过plan_id关联account_plans,说明这两个模型是属于一个AccountPlan,而非hasOne(hasOne的外键会存放在关联模型表中)。修改关联方法:
class Sponsor extends Model { protected $fillable = ['name', 'plan_id']; public function plan(){ return $this->belongsTo(AccountPlan::class); // 单数命名更符合单向关联逻辑 } } class Creator extends Model { protected $fillable = ['name', 'plan_id']; public function plan(){ return $this->belongsTo(AccountPlan::class); } }
3. 先创建Plan再关联角色
完全可以按「创建Plan → 创建角色」的顺序处理,代码示例:
// 1. 先创建AccountPlan实例,填入该模型所需字段 $plan = AccountPlan::create([ 'name' => '基础套餐', // 示例字段,需替换为实际表字段 'price' => 99 ]); // 2. 根据角色关联创建Creator/Sponsor $role = $input['role'] === 'creator' ? 'creator' : 'sponsor'; $user->$role()->create([ 'plan_id' => $plan->id, 'name' => $input['name'] ]);
如果要一次性创建3条记录,可通过循环实现(按需选择创建新Plan或复用已有Plan):
// 示例:创建3条不同角色的记录,每条对应新Plan $rolesToCreate = ['creator', 'sponsor', 'creator']; foreach ($rolesToCreate as $index => $role) { $plan = AccountPlan::create([ 'name' => "套餐{$index+1}", 'price' => 99 + $index*50 ]); $user->$role()->create([ 'plan_id' => $plan->id, 'name' => "{$input['name']}_{$index+1}" ]); }
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

