Modelos
Cómo Nibiru genera automáticamente las clases de modelos a partir de su esquema de base de datos y cómo extenderlas.
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.
Cómo funciona la generación
Sección titulada «Cómo funciona la generación»Cuando [GENERATOR] database = true en tu INI, el despachador ejecuta new Model(false) en cada solicitud, lo que hace que:
- Conecta con el controlador activo.
- Enumera las tablas en la base de datos configurada (
information_schema.tablespara PG,SHOW TABLESpara MySQL). - Para cada tabla, escribe
application/model/<table>.phpque contiene una clase que extiende el adaptadorDbrelevante e incorpora una constanteTABLEque 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 requestdatabase.overwrite = true ; if false, generator won't touch existing filesEn producción, establece database = false para que los modelos no se regeneren en cada solicitud.
Un modelo generado
Sección titulada «Un modelo generado»Para una tabla users con columnas user_id, user_login, user_pass, user_email:
<?phpnamespace 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]);Consultas personalizadas
Sección titulada «Consultas personalizadas»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``````phpnamespace 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.
Trucos para múltiples controladores
Sección titulada «Trucos para múltiples controladores»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.
Cuando saltarse el generador
Sección titulada «Cuando saltarse el generador»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.