如何按belongsToMany关联的翻译结果筛选数据?
搞定多对多关联里的翻译字段查询问题
看你这代码,是想通过Activities和Tags的多对多关联,查询Tags的翻译字段name对吧?不过当前的写法有几个小问题,我来帮你修正:
首先得确认你的Tags表已经正确加载了TranslationBehavior,然后查询时要正确关联翻译表、引用字段。给你两种可行的写法:
方法一:直接关联翻译表查询
$result = $this->Activities->find() ->leftJoinWith('Tags.TagsTranslations', function ($q) use ($request) { return $q->where([ 'TagsTranslations.name LIKE' => '%' . $request->filter . '%' ]); }) ->contain(['Tags']) ->distinct() // 多对多关联容易返回重复的Activities,加这个去重 ->all() ->toArray();
方法二:用translationField的正确姿势
要是你想继续用translationField,得注意它是表对象的方法,得从Tags表实例调用,不能直接通过关联链调用:
$tagsTable = $this->Activities->Tags; $result = $this->Activities->find() ->leftJoinWith('Tags') ->where([ $tagsTable->translationField('name') . ' LIKE' => '%' . $request->filter . '%' ]) ->contain(['Tags']) ->distinct() ->all() ->toArray();
几个关键提醒:
- 多对多关联查询时,因为关联会产生笛卡尔积,一定要加
distinct(),不然会拿到一堆重复的Activities记录。 - 确保Tags表的
TranslationBehavior配置没问题,比如指定了翻译表(默认是tags_translations),并且把name设为可翻译字段。 - 如果要过滤翻译字段,直接关联到翻译表(
Tags.TagsTranslations)的方式会更精准,也更容易排查问题。
要是你用的是CakePHP 3.x或4.x,这两种方法都能正常跑起来,根据你的实际项目版本微调细节就行~
内容的提问来源于stack exchange,提问作者Vetemi
相关产品推荐
相关产品推荐

