Paginate изнутри модели в CakePHP - PullRequest
9 голосов
/ 28 июня 2011

В моей модели Event есть функция getEvents - вы можете передать предел, start и end даты, fields, event types и событие subtypes.

Я прочитал, что paginate может принять все параметры, которые я использую, например joins, conditions, limit ... и т. Д., Как и обычная find банка.

Возвращает данные очень хорошо, когда я не пытаюсь разбивать на страницы. Но - я бы хотел иметь возможность передать ей переменную paginate, чтобы сказать это вместо того, чтобы делать это:

$this->recursive = -1;
$data = $this->find('all', $qOptions);

для этого:

$this->recursive = -1;
$data = $this->paginate($qOptions);

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

Есть ли другой лучший способ сделать что-то подобное? Я потратил достаточно времени на то, чтобы эта функция делала то, что я хочу, и позволяла передавать все параметры ... и т. Д. - это просто пустая трата времени, если я не могу также использовать ее для нумерации страниц. Но - если это не идеально, я тоже хорошо это слышу. Заранее спасибо.

EDIT:

Я читаю в Интернете другие вещи, которые говорят, что вы не должны использовать paginate в вашей модели, потому что он опирается на переменные URL, что противоречит цели структуры MVC. Это имеет смысл, но значит ли это, что мне нужно писать одинаковые соединения / запросы как в модели, так и в контроллере? И в каждом действии, что нужно?

Ответы [ 4 ]

9 голосов
/ 05 июля 2011

Я понял, как сохранить свой комплекс find в моей модели, не перезаписывая его во второй раз в контроллере, путем передачи логической переменной $paginate.

Если $paginate имеет значение true, он возвращает только созданные параметры, которые затем можно использовать при разбиении на страницы контроллера. Если это false (то есть мы не хотим разбивать на страницы), он возвращает фактические результаты события. Пока, похоже, это работает.

В моей функции getEvents() (этот метод используется в модели Events)

    if($paginate) {
        return $qOpts; // Just return the options for the paginate in the controller to use
    } else {
        $data = $this->find('all', $qOpts); // Return the actual events
        return $data;
    }

Затем в моих Событиях / Индексах (контроллер событий, действие индекса - где я знаю, что я хочу разбить на страницы):

$this->Event->recursive = -1; // (or set recursive = -1 in the appModel)
$opts['paginate'] = true;

$paginateOptions = $this->Event->getEvents($opts);

$this->paginate = $paginateOptions; // Set paginate options to just-returned options
$data = $this->paginate('Event'); // Get paginate results
$this->set('data', $data); // Set variable to hold paginated results in view
3 голосов
/ 28 июня 2011

Метод paginate() модели не принимает те же параметры, что и find(). В частности, find() хочет массив опций, но paginate() хочет, чтобы каждая опция передавалась индивидуально. См. Пользовательский запрос нумерации страниц в книге CakePHP.

Итак, вместо:

$data = $this->paginate($qOptions);

Вы хотите что-то вроде:

$data = $this->paginate($qOptions['conditions'], $qOptions['fields'], ...);

EDIT

Пользовательская модель нумерации страниц - это не та функция, которую вы вызываете. Это функция, которую вам нужно реализовать, и она будет вызываться платформой CakePHP. В примере в вашем вопросе вы пытаетесь вручную вызвать $this->paginate(...) из вашей модели. Это не работает Вместо этого сделайте это.

В вашей модели реализуйте методы paginate и paginateCount.

function paginate($conditions, $fields, ...)
{
    // return some data here based on the parameters passed
}

function paginateCount($conditions, ...)
{
    // return some rowcount here based off the passed parameters
}

Затем в вашем контроллере вы можете использовать стандартные функции нумерации страниц.

function index()
{
    $this->paginate = array('MyModel' => array(
        'conditions' => array(...),
        'fields' => array(...),
    ));

    $this->set('myobjects', $this->paginate('MyModel'));
}

Теперь функция Controller::paginate() будет извлекать условия и другие данные из параметра Controller::paginate и вместо передачи их в Model::find будет передавать их в пользовательские функции Model::paginate() и Model::paginateCount(). Таким образом, возвращаемые данные основаны на том, что вы делаете в этих двух методах, а не на стандарте find(). }

0 голосов
/ 01 июля 2011

вы можете использовать этот, который работает нормально для меня.

$ условие = "ваше условие где";$ this-> paginate = array ('fields' => array ('AsinsBookhistory.id', 'AsinsBookhistory.reffer_id', 'AsinsBookhistory.ISBN', 'AsinsBookhistory.image', 'AsinsBookhistory.title', 'AsinsBookhistory.last_updatedtime), 'условие' => $ условие, 'группа' => массив ('AsinsBookhistory.ISBN'), 'порядок' => массив ('AsinsBookhistory.last_updatedtime' => 'desc'));$ this-> set ('lastvisitedbooks', $ this-> paginate ('AsinsBookhistory'));

0 голосов
/ 29 июня 2011
Массив

$ paginate аналогичен параметрам метода Model-> find ('all'), а именно: условиям, полям, порядку, пределу, странице, содержанию, объединениям и рекурсиву.

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

var $paginate = array(
 'Event' => array (...)
 );

Или вы можете также задать условия и другие ключи в массиве $ paginate внутри вашего действия.

 $this->paginate = array(
 'conditions' => array(' ... '),
 'limit' => 10
 );
 $data = $this->paginate('Event');

Вы используете $name = 'Event' в вашем контроллере?

Если мы не будем упоминать название модели в $this->paginate(), она будет использовать модель, как указано в $name, иначе будет выглядеть в массиве var $uses и в этом случае будет получено имя модели (первое)

например, var $uses = array('Model1','Model2'); // $ name! = Упомянутый

Если вы хотите разбить на страницы по отношению к Model2 , тогда вы должны указать ModelName в массиве разбивки на страницы, например $this->paginate('Model2'), в противном случае Model1 будет рассматриваться при разбивке на страницы.

...