Paginate desde dentro de un modelo en CakePHP
cakephp-1.3 (4)
El método del modelo paginate()
no acepta los mismos parámetros que un find()
. Específicamente, find()
quiere una matriz de opciones, pero paginate()
quiere que cada opción se pase individualmente. Consulte la paginación de consultas personalizadas en el libro de CakePHP.
Entonces, en lugar de:
$data = $this->paginate($qOptions);
Quieres algo como:
$data = $this->paginate($qOptions[''conditions''], $qOptions[''fields''], ...);
EDITAR
La paginación del modelo personalizado no es una función que usted llama. Es una función que necesita implementar y será invocada por el marco de CakePHP. En el ejemplo de su pregunta, intenta llamar manualmente $this->paginate(...)
desde algún lugar de su modelo. Eso no funciona. En cambio, haz esto.
En su modelo, implemente los métodos paginate
y 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
}
Luego, en su controlador puede usar las funciones de paginación estándar.
function index()
{
$this->paginate = array(''MyModel'' => array(
''conditions'' => array(...),
''fields'' => array(...),
));
$this->set(''myobjects'', $this->paginate(''MyModel''));
}
Ahora, la función Controller::paginate()
tomará las condiciones y otros datos del parámetro Controller::paginate
y, en lugar de pasarlo a su Model::find
, lo pasará a su Custom Model::paginate()
y Model::paginateCount()
funciones Model::paginateCount()
. Por lo tanto, los datos que se devuelven se basan en lo que sea que haga en esos dos métodos y no en un estándar find()
. }
Tengo una función en mi modelo de Event
llamada getEvents
: puede pasar fechas límites, de start
y de end
, fields
, types
eventos y subtypes
eventos.
Leí que paginate
puede aceptar todos los parámetros que estoy usando como joins
, conditions
, limit
... etc, como una find
normal.
Devuelve datos muy bien cuando no intento paginar. Pero, me gustaría poder pasarle una variable de paginate
para contarlo en lugar de hacer esto:
$this->recursive = -1;
$data = $this->find(''all'', $qOptions);
para hacer esto:
$this->recursive = -1;
$data = $this->paginate($qOptions);
Cuando intento eso, sin embargo, me da muchos errores. Si es necesario, puedo especificar los errores más adelante, por ahora, supongo que estoy buscando, ¿se puede hacer algo así? ¿Si es así, cómo?
¿Hay alguna otra forma mejor de hacer algo como esto? Pasé bastante tiempo haciendo que esta función hiciera exactamente lo que quería, y permitiendo que todas las opciones pasasen ... etc. - parece una pérdida si no puedo usarla para la paginación. Pero, si no es lo ideal, estoy bien al escuchar eso también. Gracias por adelantado.
EDITAR:
Estoy leyendo otras cosas en línea que dicen que no debes usar paginate en tu modelo, porque se basa en variables de URL, lo que frustra el propósito de la estructura de MVC. Esto tiene sentido, pero ¿eso significa que tengo que escribir las mismas uniones / consultas en el modelo y el controlador? Y en cada acción que se necesita?
puedes usar este que está funcionando bien para mí.
$ condition = "su condición donde"; $ this-> paginate = array (''fields'' => array (''AsinsBookhistory.id'', ''AsinsBookhistory.reffer_id'', ''AsinsBookhistory.ISBN'', ''AsinsBookhistory.image'', ''AsinsBookhistory.title'', ''AsinsBookhistory.last_updatedtime'' ), ''condiciones'' => $ condición, ''grupo'' => matriz (''AsinsBookhistory.ISBN''), ''orden'' => matriz (''AsinsBookhistory.last_updatedtime'' => ''desc'')); $ this-> set (''lastvisitedbooks'', $ this-> paginate (''AsinsBookhistory''));
$ paginate array son similares a los parámetros del método Model-> find (''all''), es decir: condiciones, campos, orden, límite, página, contener, unir y recursivo.
Para que pueda definir sus condiciones de esta manera:
var $paginate = array(
''Event'' => array (...)
);
O también puede establecer condiciones y otras claves en la matriz $ paginate dentro de su acción.
$this->paginate = array(
''conditions'' => array('' ... ''),
''limit'' => 10
);
$data = $this->paginate(''Event'');
- http://book.cakephp.org/2.0/en/controllers.html
- http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html
¿Usas $name = ''Event''
en tu controlador?
Si no mencionaremos el nombre del modelo en $this->paginate()
, usará el modelo como se menciona en $name
contrario, busque en var $uses
array y obtendrá el nombre del modelo (el primero)
por ejemplo var $uses = array(''Model1'',''Model2'');
// $ name! = mencionado
n desea paginación con respecto al Modelo2, entonces debe especificar ModelName en la matriz de paginación como $this->paginate(''Model2'')
contrario Model1 se considerará en la paginación.
La forma en que descubrí cómo puedo mantener mi find
compleja en mi modelo sin tener que volver a escribirla por segunda vez en el controlador es pasando una variable booleana de $paginate
.
Si $paginate
es verdadero, devuelve solo las opciones creadas, que luego pueden usarse en la paginación del controlador. Si es falso (lo que significa que no queremos paginar), devuelve los resultados reales del evento. Hasta ahora, esto parece estar funcionando.
En mi función getEvents()
(este método está en el modelo de eventos)
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;
}
Luego, en mi evento / índice (controlador de eventos, acción de índice, donde sé que quiero paginación):
$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