场景
数据库中有一个字段是逗号分割的数组,页面展示和编辑的时候都是以数组的方式和服务端打交道,服务端内部自然也是以数组的方式在各函数间传递是最方便的。幸好,laravel提供的database对此也有支持(见此文档)。
我们有一个Demo模型,有一个tags字段存储逗号分割的多个tag。就有如下Model定义
<?php class Demo extends \Illuminate\Database\Eloquent\Model{ public function setTagsAttribute($value){ $this->attributes['tags'] = implode(',', $value); } public function getTagsAttribute($value){ return json_decode($value, true); } }
坑
我们要更新的时候,代码是这样的
<?php Demo::where('id', 1)->update(['tags' => ['not', 'work']]);
很好理解,查找id为1的Demo,更新它的tags为:not,work。实际执行的时候,你会发现,对方像你扔了一个Notice。。。
Notice: Array to string conversion in xxx
这个提醒已经非常明显了--我们的Mutators没有工作。
通过跟踪执行过程,发现根本就没有执行过Mutators相关的逻辑,这就很奇怪了,既然你提供了为啥不执行呢?
解决方案
Demo::find(1)->update(['tags' => ['work', 'well']]);
Laravel有基础DB和ORM之分,通过find拿到的肯定是ORM封装的对象,自然也就支持Mutators相关的逻辑了。
后话
道理我都懂,但是为什么会失败呢?!Github issue
《“laravel更新Mutators字段的巨坑”》 有 1 条评论
update:
有人回复了:
First line you use the Query Builder, second line you use Eloquent, only then your accessors work.
跟我想的是一样的,基础DB根本就不支持更多的特性,只是语法解析器而已。。。