Migraciones
Si haz trabajado en algún proyecto de desarrollo de software, sabrás que la mayoría de las veces por no decir todas, es imprescindible almacenar la información en una base de datos, para poder utilizar dicha información cuando se requiera. Entonces como parte del proceso del desarrollo de software nos vemos en la necesidad de realizar un modelamiento de dicha base de datos, por lo que tenemos que definir ciertas cosas como que gestor de base de datos utilizaremos (MySQL, SQLite, PostgreSQL, etc), o tener conocimiento previo sobre la sintaxis del lenguaje script de SQL. Es por esta razón que Laravel nos cambia el enfoque de desarrollo hacia la especificación desde código como la forma de crear una base de datos.
Laravel nos establece que no enfoquemos mucho tiempo en modelamiento o en compatibilidades de gestores de base de datos, que dejemos de lado el lenguaje script de SQL. Todo esto gracias a las migraciones las cuales nos ayuda a que podamos tener un control sobre las versiones, por ejemplo si realizamos un cambio en nuestra base de datos y no cumple con nuestra necesidad o simplemente se nos olvido cambiar algo, las migraciones nos permiten volver a un estado anterior, a si también los cambios los agregamos directamente a la migración y simplemente ejecutamos para que se realicen.
¿Como creamos una Migración?
Para crear una migración antes necesitamos saber que las migraciones para que no tengan problema a la hora de ejecutarlas y posteriormente implementadas en la base de datos, es necesario que las migraciones se creen en orden, esto se refiere a que si vamos a crear una migración que tendrá una clave foránea de otra entidad, es necesario que creemos primero la migración que necesitaremos para la creación de esta ultima.
Tenemos dos opciones para crear una migración
Primero Las migraciones se encuentran almacenadas en la ruta database/migrations/ de nuestro proyecto actual de Laravel, por defecto con la instalación se encuentran dos migraciones ya creadas create_users_table y create_password_resets_table.
La primera es la creación de la migración de forma común desde la linea de comandos:
php artisan make:migration nombre_migracion
O también podemos crear el modelo junto con la migración:
php artisan make:model NombreModelo -m
Al agregar el -m le estamos indicando que cree junto con el modelo su respectiva migración. Si revisamos el resultado veremos algo como:
2015_06_23_054801_crear_tabla_nombre.php
Donde podemos destacar la fecha de creación con la hora en que se creó para evitar que se repitan las fechas ademas de establecer el orden de prioridad al momento de ejecutar las migraciones.
Si abrimos el archivo podremos ver algo como lo siguiente:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateGenerosTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('generos', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('generos');
}
}
Función up()
En esta función nosotros especificaremos la estructura de la tabla, donde podemos ver que gracias al comando ingresado ya se encuentra creada la llamada a la función create de la clase Schema, el cual nos permite crear la tabla en nuestra base de datos,esta recibe dos parámetros, el primero es el nombre que va a recibir la tabla que si no mal recuerdan es el que se le dio en el comando y por lo cual ya se encuentra en su lugar, y el segundo parámetro es una función closure o función anónima que lo que hace es definir las columnas de nuestra tabla, a su vez esta función anónima recibe como parámetro un objeto de tipo Blueprint.
Ahora utilizaremos la variable $table para definir todos los atributos de la tabla, podemos ver que ya posee un campo id que es incrementable y la creación de los campos timestamps, nosotros para tema de simplicidad borraremos el campo timestamps y agregaremos los campos de un genero.
public function up()
{
Schema::create('generos', function (Blueprint $table) {
// se definen las respectivas columnas de la tabla
$table->increments('id_genero');
$table->string('descripcion',50);
});
}
Como podemos ver definimos el campo id_genero como incrementable predeterminado es de tipo integer y la descripción como string con un largo de 50 caracteres. Si quieres conocer que tipos de campos puedes ingresar aquí dejaremos el link de la documentación con una amplia lista.
Lista de campos para definición de tablas.
Función down()
Como ya hemos apreciado la función up crea la tabla entonces la función down sera la encargada de eliminar la tabla de la base de datos. La cual la clase Shema llama ahora al método drop para eliminar dicha tabla.
Iniciar o arrancar las migraciones de nuestra aplicación
Para ello nosotros usaremos simplemente el comando de artisan llamado migrate el cual si es su primera ejecución se dispondrá a crear cada una de las tablas definidas por las migraciones ademas de una tabla en particular llamada migrations, la que se encargará de almacenar cada uno de los cambios realizados en nuestra base de datos así teniendo un control sobre las ejecuciones de las mismas, evitando ejecutar nuevamente el mismo archivo si ya fue ejecutado previamente.
¿Como deshacer los cambios?
Como ya mencionamos anteriormente Laravel nos permite volver hacia atrás una acción en la base de datos, para ello se pude realizar de dos formas.
Con el siguiente comando lo que hará es deshacer la última migración realizada que fue registrada en la tabla migrations:
php artisan migrate:rollback
A diferencia de este ultimo el cual hará deshacer todas las migraciones registras hasta el momento en la tabla migrations.
php artisan migrate:reset
Ahora si nosotros queremos actualizar una migración haremos uso del siguiente comando:
php artisan migrate:refresh
Beneficios del uso de Migraciones
- Se posee un mayor control de las versiones de la base de datos.
- Para crear, actualizar o deshacer los cambios en la bd simplemente usamos los comandos.
- En ningún momento hacemos uso de lenguaje sql, siempre estamos trabajando con php.
- Si estamos trabajando en un equipo de desarrollo siempre se contará con la ultima versión de la base de datos si utilizamos un controlador de versiones como GIT.
- Lo mas importante si queremos migrar o exportar nuestro proyecto para trabajarlo en otra base de datos simplemente configuramos las variables de entorno para elegir el gestor con el cual trabajaremos y Laravel se encargará del resto.
Seeders
Los seeders son otro componente que nos facilita Laravel para la población de la base de datos y no emplear demasiado tiempo registrando uno por uno los datos, esto es muy útil cuando nuestro sistema requiere de una cantidad considerable de registros, donde la posibilidad de ingresarlos de a uno es simplemente inimaginable.
¿Como crear un Seeder?
Para crear un seeder no es mucha ciencia al igual que muchos de los componentes que generamos en Laravel se hace a través de nuestra interfaz de comando proporcionada por artisan, siguiendo en la linea de los ejemplos dados hasta ahora crearemos un seeder para poblar la tabla de géneros.
1. Primero ejecutaremos el siguiente comando para su creación
php artisan make:seeder GeneroSeeder
Nuestros seeders se almacenaran en el directorio database/seeds/ en nuestro caso GeneroSeeder.php, si vemos nuestro seeder recién generado veremos una clase que extiende de Seeder, como la siguiente.
<?php
use Illuminate\Database\Seeder;
class GeneroSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
}
}
Aquí podemos apreciar que el archivo generado posee una función run(), la cual como su nombre lo indica será la encargada de ejecutar nuestro seeder, entonces nosotros definiremos la creación de nuestros registros dentro de esta función de la siguiente manera.
public function run()
{
\DB::table('generos')->insert([
'id_genero' => 1,
'descripcion' => 'Terror',
]);
\DB::table('generos')->insert([
'id_genero' => 2,
'descripcion' => 'Comedia',
]);
\DB::table('generos')->insert([
'id_genero' => 3,
'descripcion' => 'Drama',
]);
\DB::table('generos')->insert([
'id_genero' => 4,
'descripcion' => 'Acción',
]);
}
Como podemos ver aquí no hacemos uso de los modelos, esto debido a que seria una mala practica hacer uso de un modelo ya que nos encontramos fuera del entorno donde se desenvuelve la aplicación, es decir los seeders no son componentes de la aplicación sino de la base de datos, por lo que no debería tener contacto con ella. Por lo que se referencia directamente a la base de dato, especificando la tabla, la función a realizar y los campos que se ingresarán.
2. Crear la referencia a nuestro seeder creado.
Antes de ejecutar nuestro seeder es necesario definirlo en el archivo DatabaseSeeder el cual es el administrador de todos los seeder que se ejecutarán. Por lo que si no esta definido en la función run() de este archivo nuestro seeder no se ejecutará.
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(GeneroSeeder::class);
}
}
Simplemente se realiza la llamada a la clase que se generó y que hemos definido.
3. Ejecutar Seeders
Después de realizar los pasos mencionados anteriormente estaremos en condiciones de ejecutar nuestro seed con el siguiente comando:
php artisan db:seed
Para finalizar solo nos quedaría revisar en nuestra base de datos si se encuentran los registros ingresados en el seed.
Como información también comentarles que existe un componente llamado Faker el cual se encuentra disponible desde la versión 5.0 de Laravel pre-instalada en nuestro proyecto. Faker nos ayudará a generar datos de prueba o aleatorios para poder realizar consultas mas realistas a nuestra base de datos, durante el proceso de desarrollo de la aplicación.