CakePHP Перевести поведение и количество страниц - PullRequest
1 голос
/ 07 декабря 2011

У меня есть модель с поведением Translate, прикрепленная с двумя полями: заголовок и описание.Я добавил некоторые условия на переводимых полях.Как обычно в разбивке на страницы, CakePHP сначала выполняет подсчет, а затем извлекает все записи.При получении итоговых записей запроса:

SELECT COUNT(DISTINCT( `product`.`id` )) AS COUNT
FROM   `products` AS `product`
   INNER JOIN `i18n` AS `i18nmodel`
     ON ( `product`.`id` = `i18nmodel`.`foreign_key`
          AND `i18nmodel`.`model` = 'Product'
          AND `i18nmodel`.`locale` = 'eng' )
   LEFT JOIN `categories` AS `category`
     ON ( `product`.`category_id` = `category`.`id` )
   LEFT JOIN `vats` AS `vat`
     ON ( `product`.`vat_id` = `vat`.`id` )
   LEFT JOIN `availables` AS `available`
     ON ( `product`.`available_id` = `available`.`id` )
WHERE  ( ( `i18n__description`.`content` LIKE '%test%' )
      OR ( `i18n__title`.`content` LIKE '%test%' )
      OR ( `product`.`code` LIKE '%test%' ) )  

я получаю:

1054: Unknown column 'I18n__description.content' in 'where clause'

, поскольку таблица i18n не объединена как заголовок i18n_ или i18n _description, ноas i18nmodel

Однако, когда разбиение на страницы пытается получить строки запроса (не общие записи), все работает нормально.Есть ли какое-нибудь решение для этого?

Код контроллера выглядит примерно так:

$condition = array();
foreach ($search as $word) {
if (strlen($word) > 0)
 $condition[] = array('OR' => array('I18n__description.content LIKE' => '%' . $word . '%','I18n__title.content LIKE' => '%' . $word . '%',
                        'Product.code LIKE' => '%' . $word . '%'));
}

$conditions = array('AND' => $condition);
$products = $this->paginate($conditions);

Ответы [ 2 ]

2 голосов
/ 05 марта 2012

Этот случай можно просто обработать, создав собственный метод paginateCount в модели, которую вы хотите разбить на страницы.

function paginateCount($conditions = array(), $recursive = null, $extra = array()) {
    return count($this->find('all', array('conditions' => $conditions)))
}
1 голос
/ 18 ноября 2013

Счетчик страниц не использует трансляционные соединения, поэтому вам нужно присоединиться вручную перед поиском. FindAll не очень хорошее решение, потому что он выполняет сложные запросы и ест ресурсы сервера.

https://github.com/cakephp/cakephp/issues/1753

Решение. Это не работает с SmoothTranslate Behavior, но небольшая модификация кода выше, это может сработать. Переопределить, прежде чем найти.

 function beforeFind($queryData){
     if(!empty($this->actsAs['SmoothTranslate']['fields'])){
        foreach($this->actsAs['SmoothTranslate']['fields'] as $trkey=>$trval){
          if(!is_string($trkey))  $trkey=$trval;

          $joinFound=false;
          foreach($queryData['joins'] as $join){
            if($join['alias']=='I18n__'.$trkey){
              $joinFound=true;  break;
            }
          }
          if(!$joinFound){
            $newJoin = array(
              'type'=>'LEFT',
              'table'=>'i18n',
              'alias'=>'I18n__'.$trkey,
              'conditions'=>array(
                $this->alias.'.id'=>Set::map(array(
                  'type'=>'identifier',
                  'value'=>'I18n__'.$trkey.'.foreign_key',
                )),
                'I18n__'.$trkey.'.model'=>$this->alias,
                'I18n__'.$trkey.'.locale'=>$this->locale,
                'I18n__'.$trkey.'.field'=>$trkey,
              ),
            );
            array_push($queryData['joins'], $newJoin);
          }
        }

    }
    return $queryData;
  }
}
...