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

♀尐吖头ヾ 提交于 2019-12-11 15:28:29

问题


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

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

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'


回答1:


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.

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

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

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.

See also

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


来源:https://stackoverflow.com/questions/48020742/cakephp-3-4-7-how-to-query-translated-content-in-contained-associations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!