CakePHP 3.4.7-如何查询包含的关联中的翻译内容? [英] CakePHP 3.4.7 - How to query translated content in contained associations?

查看:77
本文介绍了CakePHP 3.4.7-如何查询包含的关联中的翻译内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I upgraded cakephp to cakephp 3.4.7 version. My website is in multiple languages so an comment's and authors's title depends on the local. How to query translated content in contained associations? The php code in the controller looks like this:

//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();

这仅适用于默认语言,但是当我更改语言时,总是得到一个空数组。表i18n包含其他语言的评论和作者记录。在作者模型中:

This works only for the default language, but when I change the language, I get always an empty array. Table i18n contains records for 'comments' and 'authors' in other languages. In 'author' model:

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

当我根据示例更改代码时:在使用翻译行为时如何查询翻译内容?我得到以下结果:

When I changed the code according to the example:How to query translated content when using the translate behavior? I got the following results:

//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();

事实上,我的问题是第二个例子 //评论属于作者
显示以下错误:
错误:SQLSTATE [42S22]:找不到列:1054'on子句'中的未知列'Authors_title_translation.content'

In fact, my problem is second example //Comments belongsTo Authors The following error is displayed: Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Authors_title_translation.content' in 'on clause'

推荐答案

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

The problem is the order of joins being generated, it works for the hasMany association, as that association is being retrieved in a separate query, and the LIKE condition is being applied directly in the WHERE clause of that query.

如果有 belongsTo 关联,则将关联表联接到主查询中,并在<$ c中传递条件在连接 ON 子句中应用$ c> contain 配置,此配置发生在翻译表的连接之前

In case of a belongsTo association, the associated table is being joined into the main query, and the conditions passed in the contain configuration are being applied in the joins ON clause, which happens before the join for the translation table is being defined, hence the error.

您可以将条件应用于而不是主要查询:

You can either apply the conditions on the main query instead:

$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();

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

or change to the select or the subquery strategy for fetching the associated data. In both cases the associated data will be retrieved in a separate query, and the conditions will be applied in its WHERE clause:

$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()方法,以确保根据当前设置的语言环境使用正确的字段。

As mentioned in the comments, you should in any case use the translate behaviors translationField() method to ensure that the correct field is being used depening on the currently set locale.

另请参见

  • Cookbook > Database Access & ORM > Associations - Linking Tables Together > BelongsTo Associations
  • Cookbook > Database Access & ORM > Behaviors > Translate > Querying Translated Fields

这篇关于CakePHP 3.4.7-如何查询包含的关联中的翻译内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆