如何在多语言Post模型中使用Laravel/Scout数据库驱动并解决SQL歧义错误
解决SQL排序字段歧义错误
错误原因
查询同时关联了posts和translations表,两张表都包含id字段,执行order by id时数据库无法确定使用哪个表的id字段,触发Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous错误。
解决方案
1. 明确指定排序字段所属表
在控制器的查询回调中,通过orderBy方法明确指定使用posts.id进行排序,覆盖Scout默认的模糊排序:
$posti = Post::search(request('search'))->query(function ($builder) { $builder->join('translations', function ($join) { // 去掉不必要的DB::raw,Laravel会自动处理字符串绑定 $join->on('posts.id', '=', 'translations.foreign_key') ->where('translations.column_name', '=', 'body') ->where('translations.table_name', '=', 'posts'); }) // 明确指定排序字段为posts表的id ->orderBy('posts.id', 'desc'); })->get();
2. 可选:改用左连接避免过滤无翻译的文章
如果业务需要包含没有翻译内容的文章,将join改为leftJoin,避免inner join过滤掉未翻译的Post:
$builder->leftJoin('translations', function ($join) { $join->on('posts.id', '=', 'translations.foreign_key') ->where('translations.column_name', '=', 'body') ->where('translations.table_name', '=', 'posts'); })
3. 优化Scout搜索数组(可选)
你的toSearchableArray方法中'translations.value' => ' '没有实际作用,若使用数据库驱动的Scout,可调整为包含翻译字段的关联查询,或者保持当前逻辑即可,重点还是解决排序歧义问题。
额外说明
Laravel Voyager的翻译方案兼容astrotomic/laravel-translatable,你也可以利用该扩展的关联关系简化查询,比如同时搜索标题和内容的翻译:
$builder->leftJoin('translations', function ($join) { $join->on('posts.id', '=', 'translations.foreign_key') ->where('translations.locale', app()->getLocale()) // 可选:指定当前语言 ->whereIn('translations.column_name', ['title', 'body']); })
内容的提问来源于stack exchange,提问作者Mr.Davit
相关产品推荐
相关产品推荐

