2015-03-02 5 views
2

Так что у меня этот милый маленький индекс функции в моем ItemsController:Сортировка в контроллере, прежде чем постраничной() в CakePHP

public function index() { 
     $this->Item->recursive = 2; 
     $this->set('items', $this->paginate()); 
    } 

Это так, потому что я делаю кучу вычислений на afterFind (добавление поля, и сортировка по ним)

Но я хочу сортировать на уровне Контроллера, чтобы иметь возможность иметь недавний() и т. д. Если я сортирую на уровне afterFind, он будет сортироваться так каждый раз, независимо от того, контроллер - так что это не хорошо.

Как я могу сортировать на уровне контроллера и по-прежнему правильно использовать $ this-> paginate()?

FYI Вот некоторые из моих AfterFind:

public function afterFind($results, $primary = false){ 
    parent::afterFind($results, $primary); 
    foreach ($results as $key => $val) { 
     // my foreach logic calculating Item.score 
    } 
// the stuff I should be doing on a controller-to-controller basis: 
    $results = Set::sort($results, '{n}.Item.score', 'desc'); 
    return $results; 
} 

ответ

4

Это, как вы используете сортировки, используя Paginator

public function index() { 
    $this->paginate = array(
    'limit' => 10, 
    'order' => array(// sets a default order to sort by 
     'Item.name' => 'asc' 
    ) 
); 
    $items = $this->paginate('Item'); 
    $this->set(compact('items')); 
} 

На ваш взгляд:

<div class="sort-buttons"> 
 
    Sort by 
 
    <?php echo $this->Paginator->sort('name', 'By Name', array('class' => 'button')); ?> 
 
    <?php echo $this->Paginator->sort('score', 'By Score', array('class' => 'button')); ?> 
 
    <?php echo $this->Paginator->sort('date', 'By Date', array('class' => 'button')); ?> 
 
</div><!-- /.sort-buttons -->

Или, если используется для создания REST API, использовать строки запроса:

http://myapp.dev/items/index?sort=score&direction=desc 
+0

Спасибо, я думаю, это то, что я ищу - за исключением того, что он не работает. Может быть, потому, что поле «оценка» не существует в db и просто вставляется в afterFind? – itamar

+0

FYI проблема заключалась в том, что я не объявлял ее виртуальным полем. Как только я это сделал, я установил его в произвольное существующее поле, а затем вычислил его в afterFind. Меняем поля на то, что им нужно. Существует проблема лучшего, более низкого накладного способа сделать это. Но это сработало. – itamar

+0

^Интересно, можете ли вы вычислить значение этого виртуального поля непосредственно в модели вместо afterFind()? Документация по виртуальным полям: http://book.cakephp.org/2.0/ru/models/virtual-fields.html –

1

Рабочий путь для меня был в контроллер:

/****************************************************************** 
* 
******************************************************************/ 
function admin_index() { 
    $this->paginate = array(
     'News' => array(
      'order' => array(
       'News.created' => 'DESC' 
      ) 
     ) 
    ); 
    $data = $this->paginate('News'); 
    $this->set('news', $data); 
}