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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:16:29