Cakephp Pagination Сортировать данные из модели - PullRequest
3 голосов
/ 23 октября 2009

В настоящее время у меня есть запрос, который приводит к следующему набору записей:

Array ( [Contestant] => Array ( [id] => 1 [name] => test [age] => [city] => atest [telephone] => [email] => test@test.com [why_model_house] => a [highschool] => [photo] => 5329_119145013633_512383633_2487923_7196193_n0.jpg [active] => 1 ) [0] => Array ( [Contestant_votes] => 4 ) [Vote] => Array ( [id] => 1 ) )

Я могу заставить сортировку paginator-> работать со всеми данными в ней, кроме «Contestant_votes», поскольку она не принадлежит модели, в настоящее время она находится в массиве [0]

Я пытался сделать это:

        <th><?php echo $paginator->sort('Votes', '0.Contestant_votes'); ?></th> 

и это:

        <th><?php echo $paginator->sort('Votes', 'Contestant_votes'); ?></th> 

Но это не работает. Поле conestants_votes генерируется следующим запросом:

'Contestant.*, count(Vote.contestant_id) as Contestant_votes'

Так вот почему это не в модели. Есть ли способ обманным путем заставить CakePHP думать, что Contestant_votes является частью модели Contestant, или способ добавить его в paginator, чтобы я мог его отсортировать?

Заранее спасибо,

Фабиан Бренес

Ответы [ 4 ]

1 голос
/ 29 октября 2011

Это как раз то, для чего предназначены CakePHP 1.3 виртуальные поля .

В вашем случае, укажите в вашей Vote модели:

var $virtualFields = array(
    'Contestant_votes' => 'COUNT(Vote.contestant_id)'
);

Будьте осторожны - поведение этого виртуального поля изменится, если вы добавите группировку к вашему запросу.

0 голосов
/ 11 ноября 2009

2 подчеркивания не работают для всех моделей?

 var $hasOne = array(

'Rating' => array ( 'className' => 'Rating', 'fields' => array ('SUM (Rating.score) AS Location__sum', 'AVG (Rating.score) AS Location__avg', 'COUNT (Rating.score) AS Location__count'), 'group' => 'Rating.location_id', ) );

не может сгенерировать набор результатов с местоположением ['sum']

0 голосов
/ 20 января 2010

Я взял лучшую часть трех часов. Но я наконец взломал это.

Шаблон двойного подчеркивания происходит от здесь . Это расширение драйвера базы данных mysql, которое позволяет вам сделать так, чтобы добавляло любое вычисленное значение в поле .

Кроме того, мне пришлось взломать проверку поля в контроллере базы торта. Найдите блок кода вокруг строки 1000, который начинается с:

if (!empty($options['order']) && is_array($options['order'])) {
    // lots of code goes here
}

И замените весь блок (я сократил его для краткости) следующим:

if (!empty($options['order']) && is_array($options['order'])) {
 $key = key($options['order']);
 $value = $options['order'][$key];

 $key = preg_replace('/[^a-zA-Z_.]/', '', $key);

 $options['order'] = array();
 $options['order'][$key] = $value;
}

Проверка этого поля ОЧЕНЬ наивна и в основном просто применяет белый список, чтобы избежать любых простых SQL-инъекций, но ваши пользователи смогут испортить запрос, изменив URL-адрес самостоятельно. Я просто использую это для внутреннего бэкэнда, так что сейчас это нужно сделать.

Я также наткнулся на эту ссылку, казалось бы, будет менее хакерский способ сделать это в торте 1.3 (код выше был написан для 1.2.5)

0 голосов
/ 30 октября 2009

Измените столбец Contestant_votes в своем запросе, чтобы включить 2 подчеркивания (т. Е. Contestant__votes). Затем Cake automagic включит его как часть данных массива Contestant следующим образом:

Array (
    [Contestant] => Array (
        [id] => 1
        [name] => test
        [age] =>
        [city] => atest
        [telephone] => 
        [email] => test@test.com
        [why_model_house] => a
        [highschool] =>
        [photo] => 5329_119145013633_512383633_2487923_7196193_n0.jpg
        [active] => 1
        [votes] => 4
    )
    [Vote] => Array (
         [id] => 1
    )
)
...