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组件的验证逻辑上:
- 组件未定义验证规则(
rules方法),导致$this->validate()无法识别新增字段,返回的验证数组中不包含这些字段,最终写入数据库时为NULL。 - 重复调用
$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
相关产品推荐
相关产品推荐

