CakePHP 3.4.7 - 如何查询包含的关联中的翻译内容?

CakePHP 3.4.7 - How to query translated content in contained associations?

我把cakephp升级到了cakephp3.4.7版本。我的网站使用多种语言,因此评论和作者的标题取决于当地语言。 如何查询包含的关联中的翻译内容? php 控制器中的代码如下所示:

//Comments belongsTo Authors     
$this->loadModel('Comments');
    $comments = $this->Comments->find('all')->where(['Comments.active' => 1])->contain([
    'Authors' => function ($q) {
       return $q
            ->where(['Authors.title LIKE' => '%'.$this->term.'%','Authors.active' => 1])
            ->order(['Authors.position' => 'ASC']);
     }
     ])->toArray();

这仅适用于默认语言,但当我更改语言时,我总是得到一个空数组。 Table i18n 包含其他语言的 'comments' 和 'authors' 的记录。在 'author' 型号中:

$this->addBehavior('Translate', ['fields' => ['title','text']]);

当我根据示例更改代码时:我得到以下结果:

//Authors hasMany Comments - IT WORKS!!!
$this->loadModel('Authors');
$authors = $this->Authors->find('all')->where(['Authors.active' => 1])->contain([
'Comments' => function ($q) {
   return $q
        ->where(['Comments_title_translation.content LIKE' => '%'.$this->term.'%','Comments.active' => 1])
        ->order(['Comments.position' => 'ASC']);
 }
 ])->toArray();

//Comments belongsTo Authors  - IT DOES NOT WORK!!! 
$this->loadModel('Comments');
$comments = $this->Comments->find('all')->where(['Comments.active' => 1])->contain([
 'Authors' => function ($q) {
   return $q
        ->where(['Authors_title_translation.content LIKE' => '%'.$this->term.'%','Authors.active' => 1])
        ->order(['Authors.position' => 'ASC']);
 }
 ])->toArray();

其实我的问题是第二个例子//Comments belongsTo Authors 显示以下错误: 错误:SQLSTATE[42S22]:找不到列:1054 'on clause'

中的未知列 'Authors_title_translation.content'

问题是生成连接的顺序,它适用于 hasMany 关联,因为该关联是在单独的查询中检索的,并且 LIKE 条件直接应用于该查询的 WHERE 子句。

belongsTo 关联的情况下,关联的 table 被连接到主查询中,contain 配置中传递的条件被应用到连接 ON 子句,发生在 之前 正在定义翻译 table 的连接,因此出现错误。

您可以改为在主查询上应用条件:

$this->Comments
    ->find('all')
    ->where([
        $this->Comments->Authors->translationField('title') . ' LIKE' =>
            '%' . $this->term . '%',
        'Authors.active' => 1,
        'Comments.active' => 1
    ])
    ->contain([
        'Authors' => function ($q) {
            return $q->order(['Authors.position' => 'ASC']);
        }
    ])
    ->toArray();

或更改为 selectsubquery 策略以获取关联数据。在这两种情况下,关联数据将在单独的查询中检索,条件将应用于其 WHERE 子句:

$this->Comments
    ->find('all')
    ->where(['Comments.active' => 1])
    ->contain([
        'Authors' => [
            'strategy' => \Cake\ORM\Association::STRATEGY_SELECT,
            'queryBuilder' => function ($q) {
                return $q
                    ->where([
                        $this->Comments->Authors->translationField('title') . ' LIKE' =>
                            '%' . $this->term . '%',
                        'Authors.active' => 1
                    ])
                    ->order(['Authors.position' => 'ASC']);
            }
        ]
    ])
    ->toArray();

如评论中所述,在任何情况下,您都应该使用翻译行为translationField() 方法来确保根据当前设置的区域设置使用正确的字段。

另见