如何在Laravel中为数组类型输入使用Mutator生成唯一Slug
基于多语言名称生成唯一Slug的正确实现
你的问题出在当前Mutator接收的$value是包含英文和孟加拉语的数组,而非单独的英文名称,而且代码没有保存原始的name属性值,导致name字段无法正确存入数据库。以下是完整的修正方案:
1. 修正Name字段的Mutator
首先要确保既保存原始多语言名称,又提取英文名称生成slug:
public function setNameAttribute($value) { // 保存原始的多语言name数组到模型属性 $this->attributes['name'] = $value; // 提取英文名称,做非空校验 $englishName = $value['en'] ?? ''; if (!empty($englishName)) { $this->attributes['slug'] = $this->generateUniqueSlug($englishName); } }
2. 实现唯一Slug生成方法
使用Laravel的Str::slug生成基础slug,并通过循环校验确保唯一性(支持新增和更新场景):
use Illuminate\Support\Str; protected function generateUniqueSlug($name) { // 生成基础slug(自动转小写、替换空格为连字符) $baseSlug = Str::slug($name); $slug = $baseSlug; $counter = 1; // 构建查询:如果是更新操作,排除当前模型自身 $query = $this->where('slug', $slug); if ($this->exists) { $query->where('id', '!=', $this->id); } // 循环直至找到唯一的slug while ($query->exists()) { $slug = "{$baseSlug}-{$counter}"; $counter++; // 更新查询条件 $query = $this->where('slug', $slug); if ($this->exists) { $query->where('id', '!=', $this->id); } } return $slug; }
3. 关键配置
确保模型的$fillable包含name和slug字段,避免批量赋值限制:
protected $fillable = ['name', 'slug'];
效果测试
当传入你的示例JSON时:
{ "name": { "en": "This is name in English", "bn": "This is name in Bangla" } }
- 首次创建会生成slug:
this-is-name-in-english - 如果已有相同slug,会自动生成:
this-is-name-in-english-1、this-is-name-in-english-2等 - 更新模型时,不会把自身的slug判定为重复
内容的提问来源于stack exchange,提问作者Nafis Chonchol
相关产品推荐
相关产品推荐

