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

Laravel新增Model字段创建后始终为NULL问题求助

问题

我有一个名为Article的Model,原本包含title、subtitle、body三个属性,功能正常。但添加subtitle2、body2、subtitle3、body3四个字段后,创建文章时这些新增字段始终为NULL。已排查迁移文件、$fillable、Livewire组件及表单,仍未找到原因。

相关代码

迁移文件

public function up()
{
    Schema::table('articles', function (Blueprint $table) {
        $table->string('subtitle2')->nullable()->default(null);
        $table->text('body2')->nullable()->default(null);
        $table->string('subtitle3')->nullable()->default(null);
        $table->text('body3')->nullable()->default(null);
        
    });
}

Model文件(app/Http/Models/Article.php)

protected $fillable = [
    'title',
    'subtitle',
    'body',
    'subtitle2',
    'body2',
    'subtitle3',
    'body3',
];

Livewire组件(app/Http/Livewire/CreateArticle.php)

class CreateArticle extends Component
{
    use WithFileUploads;

    public $title;
    public $subtitle;
    public $body;
    public $category;

    public $subtitle2;
    public $body2;

    public $subtitle3;
    public $body3;

    public $temporary_images;
    public $images = [];

    public $article;
    
    public function store()
    {
        $this->validate();

        $this->article = Category::find($this->category)->articles()->create($this->validate());
        
        $this->article->user()->associate(Auth::user());
        $this->article->save();
        
        if(count($this->images)){
            foreach($this->images as $image){
                $newImage = $this->article->images()->create(['path'=>$image->store('images', 'public')]);
                
                dispatch(new ResizeImage($newImage->path, 600, 400));
            }
        }          
    }
}

表单代码

{{-- 第二段副标题 --}}
<div class="mb-3">
    <label for="subtitle2" class="form-label">Second paragraph subtitle</label>
    <input type="text" wire:model="subtitle2" class="form-control" id="subtitle2">
</div>

{{-- 第二段内容 --}}
<div class="mb-3">
    <label for="body2" class="form-label">Second paragraph</label><br>
    <textarea class="form-control" wire:model="body2" id="body2" cols="30" rows="3"></textarea>
</div>

{{-- 第三段副标题 --}}
<div class="mb-3">
    <label for="subtitle3" class="form-label">Third paragraph subtitle</label>
    <input type="text" wire:model="subtitle3" class="form-control" id="subtitle3">
</div>

{{-- 第三段内容 --}}
<div class="mb-3">
    <label for="body3" class="form-label">Third paragraph</label><br>
    <textarea class="form-control" wire:model="body3" id="body3" cols="30" rows="3"></textarea>
</div>

补充信息:

  • 调用dd($this)确认Livewire组件已正确获取到subtitle2、body2、subtitle3、body3的输入值
  • 通过Tinker查询数据库,确认这些新增字段均为NULL

解决方法

问题出在Livewire组件的验证逻辑上:

  1. 组件未定义验证规则(rules方法),导致$this->validate()无法识别新增字段,返回的验证数组中不包含这些字段,最终写入数据库时为NULL。
  2. 重复调用$this->validate()属于冗余操作,且可能导致数据丢失。

修复步骤:

1. 添加验证规则

在Livewire组件中新增rules方法,包含所有需要处理的字段:

protected function rules()
{
    return [
        'title' => 'required|string|max:255',
        'subtitle' => 'nullable|string|max:255',
        'body' => 'required|string',
        'category' => 'required|exists:categories,id',
        'subtitle2' => 'nullable|string|max:255',
        'body2' => 'nullable|string',
        'subtitle3' => 'nullable|string|max:255',
        'body3' => 'nullable|string',
    ];
}

2. 优化store方法

只调用一次validate()并保存结果,避免重复验证:

public function store()
{
    $validatedData = $this->validate();

    $this->article = Category::find($this->category)->articles()->create($validatedData);
    
    $this->article->user()->associate(Auth::user());
    $this->article->save();
    
    if(count($this->images)){
        foreach($this->images as $image){
            $newImage = $this->article->images()->create(['path'=>$image->store('images', 'public')]);
            
            dispatch(new ResizeImage($newImage->path, 600, 400));
        }
    }          
}

这样修改后,验证后的数组会包含所有新增字段,写入数据库时就能正确保存值了。

内容的提问来源于stack exchange,提问作者Dario Parrinello

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:05:29