Ir al contenido
Nibiru docsv0.9.2

Modelos

Cómo Nibiru genera automáticamente las clases de modelos a partir de su esquema de base de datos y cómo extenderlas.

Stable Reading time ~ 3 min Edit on GitHub

La capa de modelos de Nibiru es primero-esquema. No escribes los modelos a mano — el marco lee tu base de datos y genera una clase PHP por tabla en cada inicio.

Cuando [GENERATOR] database = true en tu INI, el despachador ejecuta new Model(false) en cada solicitud, lo que hace que:

  1. Conecta con el controlador activo.
  2. Enumera las tablas en la base de datos configurada (information_schema.tables para PG, SHOW TABLES para MySQL).
  3. Para cada tabla, escribe application/model/<table>.php que contiene una clase que extiende el adaptador Db relevante e incorpora una constante TABLE que describe las columnas.

Volver a ejecutar es barato: el generador sobrescribe solo cuando el esquema ha cambiado, por lo que los modelos registrados mantienen sus métodos manuscritos si cambias database = false después del primer ejecución.

[GENERATOR]
database = true ; regenerate models on each request
database.overwrite = true ; if false, generator won't touch existing files

En producción, establece database = false para que los modelos no se regeneren en cada solicitud.

Para una tabla users con columnas user_id, user_login, user_pass, user_email:

<?php
namespace Nibiru\Model;
use Nibiru\Adapter\MySQL\Db;
class users extends Db
{
const TABLE = [
'table' => 'users',
'field' => [
'user_id' => 'user_id',
'user_login' => 'user_login',
'user_pass' => 'user_pass',
'user_email' => 'user_email',
],
];
public function __construct() {
self::initTable(self::TABLE);
}
}

El adaptador Db te proporciona simples ayudantes CRUD a través de Pdo:: (o el controlador activo):

$users = new \Nibiru\Model\users();
// Read by primary key
$row = \Nibiru\Pdo::fetchRowInArrayById('users', ['user_id' => 42]);
// Read all
$all = \Nibiru\Pdo::fetchAll('SELECT * FROM users WHERE user_account_active = 1');
// Insert
\Nibiru\Pdo::insert('users', [
'user_login' => 'marduk',
'user_email' => 'marduk@nibiru.local',
]);
// Update
\Nibiru\Pdo::update('users',
['user_email' => 'new@nibiru.local'],
['user_id' => 42]);
// Delete
\Nibiru\Pdo::delete('users', ['user_id' => 42]);

La clase generada es una clase PHP simple — añade métodos libremente:

namespace Nibiru\Model;
use Nibiru\Adapter\MySQL\Db;
use Nibiru\Pdo;
class documentation extends Db
{
const TABLE = [
'table' => 'documentation',
'field' => [
'id' => 'id', 'title' => 'title', 'slug' => 'slug',
'content' => 'content', 'category' => 'category',
'version' => 'version',
],
];
public function __construct() { self::initTable(self::TABLE); }
public function getBySlug(string $slug): ?array {
return Pdo::fetchRowInArrayById(
self::TABLE['table'],
[self::TABLE['field']['slug'] => $slug]
) ?: null;
}
public function search(string $query): array {
$sql = 'SELECT * FROM ' . self::TABLE['table']
. ' WHERE title LIKE :q OR content LIKE :q ORDER BY title';
return Pdo::fetchAll($sql, [':q' => '%' . $query . '%']);
}
}

Si el generador se ejecuta nuevamente con database.overwrite = true, reemplazará este archivo. Mantenga los métodos personalizados en una clase secundaria o establezca database.overwrite = false después de la primera generación.

Patrón: modelo delgado + módulo de complemento

Sección titulada «Patrón: modelo delgado + módulo de complemento»

Para dominios complejos (autenticación, facturación, análisis), las aplicaciones de demostración colocan los métodos de consulta en un módulo de complemento en lugar del modelo sin procesar. El complemento posee las reglas de negocio; el modelo es solo un identificador tipado para la tabla:

application/module/users/
├── plugins/
│ └── user.php # User::isAuthorized(), User::loginForm(), …
└── traits/
└── userForm.php
``````php
namespace Nibiru\Module\Users\Plugin;
use Nibiru\Model\users;
class User {
private users $usersModel;
public function __construct() { $this->usersModel = new users(); }
public function isAuthorized(): bool {
return isset($_SESSION['auth']['user_id']);
}
public function findByLogin(string $login): ?array {
return \Nibiru\Pdo::fetchRow(
'SELECT * FROM users WHERE user_login = :login',
[':login' => $login]
) ?: null;
}
}

Esto mantiene los controladores ligeros ($this->user->isAuthorized()) mientras deja el modelo generado intacto.

El adaptador generado Db es específico del controlador. Si cambias de MySQL a PostgreSQL, regenera los modelos para que extiendan la clase base correcta:

  • MySQL / PDO → Nibiru\Adapter\MySQL\Db
  • PostgreSQL (libpq) → Nibiru\Adapter\PostgreSQL\Db
  • ODBC → Nibiru\Adapter\Odbc\Db

Mismos ayudantes de consulta, diferente adaptador por debajo.

Bases de datos de solo lectura, sistemas de proveedores o cualquier esquema que no controle: establezca database = false, escriba manualmente clases de modelo mínimas que coincidan con las columnas que realmente utilice y regístrelas.