Crear modelos en CodeIgniter 4
Índice de contenido
- Propiedades Principales en los Modelos
- $returnType
- $createdField
- $validationRules
- $table
- $primaryKey
- $useAutoIncrement
- $returnType
- $useSoftDeletes
- $allowedFields
- $useTimestamps
- $createdField
- $updatedField
- Operaciones comunes
- Joins
- Paginados
- Condiciones where
- Anidados con condiciones orWhere
- Condiciones Like
- Agrupadas
- Ver query compilado
- Columnas de tipo created_at y updated_at
- Relaciones de tipo foráneas
- Migración de la tabla a relacionar
- Migración de la FK o clave foránea
- Modelos
- Extra: Crear un registro con relación foránea
- Otros datos sobre los modelos
- Consultas joins para la base de datos en CodeIgniter 4
- Puntos claves
Ahora vamos a ver cómo podemos crear un componente fundamental en nuestro MVC, que viene siendo el componente que nos permite trabajar con la capa de los datos usando las migraciones en CodeIgniter 4 que creamos antes, que no puede ser otro que el modelo, el modelo simplemente es una clase, al igual que ocurre con otros frameworks como Laravel que extiende de Model, para el modelo, a diferencia de la versión 3, tenemos que definir varios atributos para poder emplearla o que sean funcionales.
Recuerda que la función primaria de un modelo es conectar un modelo con una tabla en la base de datos.
Tenemos que indicar los campos insertables es decir, aquellos campos que nosotros vamos a emplear para administrar dicha tabla vinculada a la tabla; en otras palabras las columnas; por ejemplo, vamos a a partir que tenemos una tabla como la siguiente:

Por lo tanto, queremos administrar todas las columnas de la tabla de la base de datos anterior para nuestro modelo, y siguiendo lo comentado anteriormente:
También tenemos que indicar la propiedad llamada table, para indicar con qué tabla hace match nuestro modelo con que tabla en la base de datos configurada:
<?php
namespace App\Models; // Ajusta el namespace según tu estructura
use CodeIgniter\Model; // O la clase Model que corresponda a tu framework
class MovieModel extends Model
{
/**
* @var string Nombre de la tabla de la base de datos.
*/
protected $table = 'movies';
/**
* @var string Clave primaria de la tabla.
*/
protected $primaryKey = 'id';
/**
* @var string[] Campos de la tabla que están permitidos ser rellenados (insertados/actualizados).
*/
protected $allowedFields = [
'title',
'description',
'category_id',
];
}Propiedades Principales en los Modelos
Estas por nombrar las propiedades más importantes que puedes emplear para definir el modelo, puedes ver el resto de las propiedades que puedes definir para el modelo en la documentación oficial; algunas propiedades muy interesantes serían por ejemplo.
$returnType
Aquí podemos indicar si deseamos que por defecto la data que podemos obtener realizando consultas tipo select a la base de datos, los devuelva en una estructura tipo array ('array') o tipo objeto ('object').
$createdField
Aquí podemos indicar el nombre del campo para la fecha de creación, y el mismo será establecido cuando creamos un nuevo registro.
$validationRules
Con esta propiedad podemos indicar las reglas de validación sobre las columnas de nuestro modelo que se emplearán en la fase de creación y actualización.
Otras propiedades importantes de los modelos en CodeIgniter 4:
La capa de modelos en el patrón de diseño MVC (Modelo-Vista-Controlador) es la capa que se encarga de la lógica de negocio y la comunicación con la base de datos. Es decir, es la capa que realiza las operaciones CRUD (Crear, Leer, Actualizar y Eliminar) en una base de datos, usualmente un modelo gobierna una tabla en la base de datos. Veamos las propiedades más comunes que podemos aplicar sobre nuestros modelos en CodeIgniter 4 y para qué sirven.
$table
Especifica la tabla de la base de datos con la que trabaja este modelo.
$primaryKey
Este es el nombre de la columna que identifica de manera única los registros en esta tabla. Esto no necesariamente tiene que coincidir con la clave principal que se especifica en la base de datos; se usa con métodos como find() para saber con qué columna hacer coincidir el valor especificado.
$useAutoIncrement
Especifica si la tabla usa una función de incremento automático para $primaryKey. Si se establece en falso, eres responsable de proporcionar el valor de la clave principal para cada registro de la tabla.
$returnType
Esta configuración permite definir el tipo de datos que se devuelven. Los valores válidos son 'array' (el valor predeterminado), 'objeto' o el nombre completo de una clase que se puede usar con el método getCustomResultObject() del objeto Result.
$useSoftDeletes
Si es verdadero, cualquier llamada al método delete() establecerá delete_at en la base de datos, en lugar de eliminar la fila. Esto puede preservar los datos cuando se puede hacer referencia a ellos en otro lugar, o puede mantener una "papelera de reciclaje" de objetos que se pueden restaurar, o incluso simplemente preservarlos como parte de un seguimiento de seguridad. Si es verdadero, los métodos find*() solo devolverán filas no eliminadas, a menos que se llame al método withDeleted() antes de llamar al método find*().
$allowedFields
Este array debe actualizarse con los nombres de campo que se pueden configurar durante los métodos save(), insert() o update(). Cualquier nombre de campo que no sea este, será descartado. Lo cual ayuda a proteger la integridad de las columnas que no queremos que la aplicación pueda interactuar.
$useTimestamps
Este valor booleano determina si la fecha actual se agrega automáticamente a todas las inserciones y actualizaciones. Si es verdadero, establecerá la hora actual en el formato especificado por $dateFormat. Esto requiere que la tabla tenga columnas denominadas created_at y updated_at en el tipo de datos adecuado.
$createdField
Especifica qué campo de base de datos usar para la marca de tiempo de creación de registro de datos.
$updatedField
Especifica qué campo de la base de datos debe usarse para mantener la marca de tiempo de actualización del registro de datos.
Estos son algunas de las configuraciones más comunes y puedes ver la lista completa aquí:
https://codeigniter.com/user_guide/models/model.html#id6
Operaciones comunes
Como en cualquier framework MVC, los modelos son otra de las capas del MVC y es la capa que permite conectarse a la base de datos. Un modelo se utiliza para interactuar con la base de datos y realizar operaciones de gestión sobre la misma, es decir, crear, actualizar, eliminar y obtener detalles de registros, cada modelos esta atado a una tabla en la base de dato, los modelos son la única forma de acceso a la base de datos.
Para crear un modelo en CodeIgniter 4, se puede utilizar el CLI con el siguiente comando:
$ php spark make:model NombreDelModeloEste comando creará una nueva clase para el modelo en app/Models. También puede indicar propiedades para personalizar la conexión como el nombre de la PK, tabla, funciones personalizadas y un largo etc.
Una vez que se ha creado un modelo, se puede utilizar en un controlador o en cualquier otro lugar de la aplicación para interactuar con la base de datos.
Funciones claves en los modelos
Aparte de las operaciones que ya hemos realizado, hay muchas combinaciones que puedes realizar según tus necesidades; veamos algunas que podemos realizar en CodeIgniter 4.
Joins
Los joins se emplean para combinar resultados entre distintas tablas buscando por el campo relacional; en CodeIgniter tenemos distintos tipos de joins (left, right, inner…) al igual que tenemos en SQL; como primer parámetro de la función join() pasamos la tabla a relacionar, y como siguiente parámetro, la igualdad.
$peliculaModel->asObject()
->select('peliculas.*, categorias.titulo as categoria')
->join('categorias, 'categorias.id = peliculas.categoria_id')
->find()Paginados
Esta función también puede ser simulada en SQL, aunque en CodeIgniter vamos un paso más allá; más adelante veremos cómo emplear esta función en detalle; pero en esencia es emplear la función de paginate() indicando el como parámetro el nivel de paginado.
$peliculaModel->asObject()
->select('peliculas.*, categorias.titulo as categoria')
->join('categorias, 'categorias.id = peliculas.categoria_id')
->paginate(10)Condiciones where
Los wheres son fundamentales en la mayoría de las consultas que realizamos y por ende los tienes que tener presentes; recibe dos parámetros que corresponden a la columna a comparar y su valor.
$peliculaModel->asObject()
->select('peliculas.*, categorias.titulo as categoria')
->join('categorias, 'categorias.id = peliculas.categoria_id')
->where('categorias.id', $categoria_id')
->find()Anidados con condiciones orWhere
Similar al caso anterior, pero aplicando las condiciones or en vez de la de where:
$usuarioModel->orWhere('email', $email)->orWhere('usuario', $usuario)->first();Condiciones Like
Los like son muy usados cuando estamos realizando búsquedas parciales; su uso es similar a de los where:
$peliculaModel->asObject()
->select('peliculas.*, categorias.titulo as categoria')
->join('categorias, 'categorias.id = peliculas.categoria_id')
->like('peliculas.titulo', $buscar)
->find()Agrupadas
En este ejemplo vemos cómo usar la función de groupBy para agrupar por campos similares; (según la versión de MySQL que estés empleando pueda que los campos a agrupar tengan que coincidir con las columnas especificadas en el select) cuya función en CodeIgniter te permite devolver justamente las columnas que especifiques, indicando alias en el proceso.
$peliculaModel->asObject()
->select('peliculas.*, categorias.titulo as categoria')
->join('categorias, 'categorias.id = peliculas.categoria_id')
->join('imagenes', 'peliculas.id = pelicula_id', 'left')
->groupBy('peliculas.id');
->find()Ver query compilado
Finalmente, cuando estés armando tus consultas, muchas veces quieres ver el SQL generado para saber exactamente cómo estas armando la consulta, ya que, con la estructura en base a funciones para crear un query, muchas veces no queda del todo claro.
Para ver el query, necesitamos obtener una instancia de la clase 'Query Builder de CodeIgniter' con la cual, tenemos una instancia genérica para conectarnos a cualquier tabla sin emplear un modelo:
$db = \Config\Database::connect();
$builder = $db->table('peliculas');Con el query, en vez de emplear funciones finales como get() o first() empleamos la función de getCompiledSelect() en su lugar:
return $builder->limit(10, 20)->getCompiledSelect();Y obtenemos:
SELECT * FROM `peliculas` LIMIT 20, 10Lo más importante es notar que existen equivalencias entre los tipos de consulta que podemos usar en SQL, con un conjunto de funciones que tenemos en CodeIgniter; estas funciones se aprenden con la práctica, conocer cuáles parámetros debes pasar, cuales son opcionales como los puedes personalizar.
Este material forma parte de mi curso y libro completo sobre CodeIgniter 4.
Columnas de tipo created_at y updated_at
Que tengamos la ventaja de definir un campo que se llene automáticamente con la fecha actual al momento de creación del registro y más interesante, que cuando editemos ese registro, se defina la fecha actual, es algo sumamente sencillo en frameworks como Laravel y que en CodeIgniter 4, también podemos emplear de manera sencilla.
Para tal hazaña que es comparable con los logros de los Dioses... necesitamos definir unos 3 atributos en nuestro modelo:
- $useTimestamps - Booleano que indica si vas a habilitar el timestamp para la creación y actualización.
- $createdField - Définies el nombre de la columna del campo de creación.
- $updatedField - Définies el nombre de la columna del campo de actualización.
Por ejemplo, en el siguiente modelo, definimos las propiedades correspondientes junto con los 3 señalados anteriormente:
<?php
namespace App\Models;
use CodeIgniter\Model;
class ProductsControlModel extends Model
{
protected $table = 'products_control';
protected $primaryKey = 'id';
protected $allowedFields = ['product_id', 'type','count', 'created_at', 'updated_at'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';Relaciones de tipo foráneas

Las relaciones son el corazón de las base de datos relacional, las relaciones son un conjunto de reglas que describen cómo las tablas en la base de datos se relacionadas entre sí; y de aquí el nombre de relación. En una base de datos relacional, los datos se organizan en tablas, y cada tabla representa una entidad u objeto; pero muchas veces se relacionan entre si, si tenemos una relación carro, los carros tienen marcas, por lo tanto, podemos tener una tabla para los carros y otra para las marcas y las relacionamos entre si mediante el identificador único que se asigna a cada tabla, es decir, la PK.
Esta clave primaria cuando es establecida en la tabla a relacionar (en este ejemplo, debemos de registrar la PK de la tabla de modelos en la tabla de carros) se conoce como una restricción de tipo FOREIGN KEY o clave foránea en español. Veamos como manejarla en CodeIgniter 4.
Migración de la tabla a relacionar
En CodeIgniter 4, al igual que ocurre con Laravel, para poder estructurar este tipo de relaciones, tenemos que definirlas desde las migraciones; en este ejemplo, voy a tomar un par de tablas de mi curso completo, las de movies y categorías en la cual una movie o película pertenece a una categoría; primero la migración de la tabla a relacionar, es decir, la de movies:
<?php namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class Categories extends Migration
{
public function up(){
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => TRUE,
'auto_increment' => TRUE
],
'title' => [
'type' => 'VARCHAR',
'constraint' => '255',
],
]);
$this->forge->addKey('id', TRUE);
$this->forge->createTable('categories');
}
//--------------------------------------------------------------------
public function down()
{
$this->forge->dropTable('categories');
}
}Lo típico, un campo id y nombre para las categorías y en la función down hacemos las operaciones inversas a la de uno, que si en la de up creamos una tabla, por el down la destruimos; recuerda que el tema de las migraciones en CodeIgniter ya fue tratado.
Migración de la FK o clave foránea
Finalmente la tabla que vamos a relacionar mediante la foreign key:
<?php namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class Movies extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => TRUE,
'auto_increment' => TRUE
],
title=> [
'type' => 'VARCHAR',
'constraint' => 255
]
'category_id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => TRUE
],
****
]);
$this->forge->addKey('id', TRUE);
$this->forge->addForeignKey('category_id' , categories,'id','CASCADE','CASCADE');
$this->forge->createTable('movies');
}
//--------------------------------------------------------------------
public function down()
{
$this->forge->dropTable('movies');
}
}Una migración con un campo ID para mantenerla sencilla y el resto de los campos que de manera ejemplificada solamente tenemos el del título; lo importante de aquí es la columna llamada category_id que con la misma más adelante la empleamos para definir la clave foránea mediante la función de addForeignKey, la cual recibe:
- El nombre de la columna en movies, es decir, la tabla que mantendrá la relación FK
- El nombre de la tabla a relacionar, categories en nuestro caso
- La columna de la tabla a relacionar, es decir, la PK de categorías que se llama id
Modelos
Finalmente, los modelos de las migraciones anteriores:
<?php namespace App\Models;
use CodeIgniter\Model;
class MovieModel extends Model
{
protected $table = 'movies';
protected $primaryKey = 'id';
protected $allowedFields = ['title','category_id'];
}
<?php namespace App\Models;
use CodeIgniter\Model;
class CategoryModel extends Model
{
protected $table = 'categories';
protected $primaryKey = 'id';
protected $allowedFields = ['title'];
public function get($id = null)
{
if ($id === null) {
return $this->findAll();
}
return $this->asArray()
->where(['id' => $id])
->first();
}
}Extra: Crear un registro con relación foránea
Para crear un registro no tienes que definir alguna regla y estructura adicional; la relación FK a la final es una columna de tipo entero con una restricción extra que es el de la FK; así que, pasamos directamente el valor de la clave a relacionar; en este ejemplo, estamos suponiendo que estos datos son recibidos desde un formulario:
$movie = new MovieModel();
if ($this->validate('movies')) {
$id = $movie->insert([
'title' => $this->request->getPost('title'),
'description' => $this->request->getPost('description'),
'category_id' => $this->request->getPost('category_id'),
]);Otros datos sobre los modelos
- En los modelos va nuestra lógica de negocios, componentes como funciones específicas que queramos emplear dentro de la app, como obtener todos o un conjunto de registros son simplemente funciones que creamos para cada proceso; por ejemplo, una función para obtener todos los registros.
- Cuando trabajamos con las consultas, existen funciones que podemos emplear de gratis (ya las provee el framework) para trabajar con los registros; por ejemplo, el método llamado find, para obtener un registro, o el first, insertar, save, update cuyos nombres se auto explican o nos indican qué función realizan.
- Los modelos son un componente que hacen juego con las migraciones, ya que es lo usual que exista una correspondencia entre uno a uno entre las tablas, migraciones y modelos, en el caso de CodeIgniter 4, las migraciones son un archivo y composición aparte que la del modelo, es decir, son independientes, a diferencia de otros framework como Django o Flask, cuya composición de las migraciones se generar a partir de los modelos.
Consultas joins para la base de datos en CodeIgniter 4

En SQL, los JOINs son una operación que se utiliza para combinar dos o más tablas relacionales basadas en una columna o conjunto de columnas comunes, generalmente se usan las columnas de tipo FK o claves foráneas para hacer esta conexión entre distintas tablas. Se utilizan para recuperar datos de varias tablas relacionadas, permitiendo que los datos se presenten de manera más completa y significativa; por ejemplo, si tenemos una tabla de posts y otra de categorías, podemos indicar que un post contiene una categoría mediante una FK en la tabla de posts y luego, hacer un JOIN que permite conectar la tabla de posts con la de categoría y obtener el detalle completo del post; esto mismo podemos hacer con múltiples tablas.
Existen diferentes tipos de JOINs en SQL, como INNER JOIN, LEFT JOIN, RIGHT JOIN y FULL OUTER JOIN, cada uno con un propósito diferente según la necesidad del usuario.
En la aplicación CodeIgniter 4, según la documentación, tenemos 3 tipos de uniones disponibles. Aquí están los siguientes:
- Inner Join
- Left Join
- Right Join
- Inner Join: esta unión trae los datos sobre la base de una condición de valor común entre dos o más de dos tablas. De acuerdo con la condición coincidente, traerá todos los datos que esperábamos. Elimina aquellas filas del conjunto de resultados que no tienen una condición coincidente.
- Left Join: esto también funciona igual que la condición coincidente entre dos o más de dos tablas. Pero en este caso también obtenemos las filas de la tabla de la izquierda que no coinciden con la condición de la tabla del lado derecho. Significa que obtenemos todas las filas de la tabla de la izquierda, incluidos los valores de la tabla de la derecha.
- Right Join: filas con las mismas condiciones coincidentes, incluidas todas las filas del lado derecho sin ninguna condición coincide.
El uso de los joins en CodeIgniter 4 es muy fácil y lo único que tenemos que hacer es, armar la consulta principal:
$query = $productModel->asObject()->select("pc.*, u.email, puc.description, puc.direction")En este caso un modelo de ejemplo, llamado "productModel" y ahora, vamos a realizar el o los joins:
$query = $productModel->asObject()->select("pc.*, u.email, puc.description, puc.direction")
->join('products_control as pc', 'pc.product_id = products.id')En el cual, puedes colocar tantos joins como necesites y/o permitan tus relaciones, en mi caso, un producto, tiene una relación foránea con "'products_control" y "'products_control" una relación foránea (fk) con "users" y finalmente con "'products_users_control"
$query = $productModel->asObject()->select("pc.*, u.email, puc.description, puc.direction")
->join('products_control as pc', 'pc.product_id = products.id')
->join('users as u', 'pc.user_id = u.id')
->join('products_users_control as puc', 'pc.id = puc.product_control_id');Puntos claves
La función join recibe dos parámetros de manera obligatoria y un tercer opcional.
- Como primer parámetro indicamos el nombre de la tabla la cual queremos unir.
- De manera opcional, indicamos un alias mediante "as" para evitar repetir el nombre de la tabla cuando queremos referenciar la tabla: products_control as pc
- Como segundo parámetro indicamos la condición; que generalmente es colocar la igualdad de nuestra relación (fk)
- Como tercer parámetro puedes especificar el tipo de join: left, right, outer, inner, left outer, and right outer: join('products_control as pc', 'pc.product_id = products.id','left')
Sin mas que decir, las relaciones que empleamos en mi curso completo sobre CodeIgniter 4:
class ProductModel extends Model
{
protected $table = 'products';
protected $primaryKey = 'id';
protected $allowedFields = ['name', 'code', 'description', 'entry', 'exit', 'stock', 'price'];
public function get($id = null)
{
if ($id === null) {
return $this->findAll();
}
return $this->asArray()
->where(['id' => $id])
->first();
}
}
class ProductControlModel extends Model
{
protected $table = 'products_control';
protected $primaryKey = 'id';
protected $allowedFields = ['product_id', 'type','count', 'created_at', 'updated_at','user_id'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
public function get($id = null)
{
if ($id === null) {
return $this->findAll();
}
return $this->asArray()
->where(['id' => $id])
->first();
}
}
class ProductUserControlModel extends Model
{
protected $table = 'products_users_control';
protected $primaryKey = 'id';
protected $allowedFields = ['product_id', 'user_id', 'product_control_id', 'type', 'count', 'created_at', 'updated_at', 'description', 'direction'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
public function get($id = null)
{
if ($id === null) {
return $this->findAll();
}
return $this->asArray()
->where(['id' => $id])
->first();
}
}
<?php
class User extends BaseController{
use ResponseTrait;
}Los JOINS, siempre los usamos para obtener los datos de varias tablas; administrar uniones en SQL es difícil, pero trabajar en CodeIgniter también es sencillo de usar. Es una combinación izquierda o una combinación derecha en CodeIgniter.
Solo necesitamos llamar a un método en CodeIgniter $this->db->join('table'.'condition','left,right'). Las uniones toman tres parámetros: primero es la tabla, el segundo es la condición y el tercero es la unión izquierda o la unión derecha en CodeIgniter.
Siguiente paso, genera datos de prueba mediante los Seeders en CodeIgniter 4.
Acepto recibir anuncios de interes sobre este Blog.
Vamos a trabajar con la capa de los modelos en CodeIgniter 4 que viene siendo una de las capas de nuestro MVC que nos permite trabajar con los datos; y vamos a conocer todas las propiedades principales de los modelos en C4.