La conexión y manejo con bases de datos en Laravel es ridículamente fácil. La robustez con que se trabaja el código lo hace un framework todavía más sencillo de comprender. Por eso, en esta entrada se va a recoger todo lo que se necesita saber del manejo de bases de datos en Laravel: migraciones y seeders.
Conexión a la Base de Datos
El archivo de configuración para la conexión a una base de datos se encuentra en /config/database.php. Actualmente, Laravel es capaz de reconocer 4 sistemas de bases de datos: MySQL, Postgres, SQLite y SQL Server.
Si nuestro sistema escogido es MySQL se debe configurar el siguiente bloque:
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ],
En este ejemplo se va a configurar la conexión a una base de datos llamada ‘agenda_db’ que se encuentra en un servidor local. El bloque importante sería este:
'host' => '127.0.0.1', 'port' => env('DB_PORT', '3306'), 'database' => 'agenda_db', 'username' => 'root', 'password' => '',
Los únicos que ha habido son el host, database, username y password de los atributos del array. Obviamente, tienen que coincidir con agenda_db, sino no valdría de nada.
Crear migraciones
Las encargadas de las versiones de las bases de datos en Laravel se llaman migraciones. Estos archivos permiten tener actualizados y controlados los esquemas para las tablas.
Para crear una migración, Artisan cuenta con el comando make:migration. A este se le añade el nombre de la migración y se creará un archivo de clase dentro de /database/migrations
php artisan make:migration create_table_contactos
Opcionalmente el comando puede aceptar –create y —table para indicar el nombre de las tablas que se van a crear o manipular.
php artisan make:migration create_table_telefonos --create=telefonos php artisan make:migration add_foreign_key_contactos --table=telefonos
El resultado de estos comandos serían 3 archivos de migraciones que heredan de la clase Migration. Y dentro contiene dos métodos: up y down.
El método up será el primero en ejecutarse y contiene el esquema de creación o edición de las tablas. mientras que down es el encargado de revocar las acciones o eliminar tablas.
En Laravel nos valemos de Schema Builder para crear o modificar tipos de campos. A continuación voy a poner las estructuras para las tablas:
class CreateTableContactos extends Migration { public function up() { Schema::create('contactos', function (Blueprint $table) { $table->increments('id'); $table->string('nombre'); $table->string('apellidos'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('contactos'); } }
class CreateTableTelefonos extends Migration { public function up() { Schema::create('telefonos', function (Blueprint $table) { $table->increments('id'); $table->string('telefono'); $table->enum('tipo', ['fijo','movil']); $table->integer('id_contacto')->unsigned(); // esta es una clave foranea $table->timestamps(); }); } public function down() { Schema::dropIfExists('telefonos'); } }
Y la última migración que se creó fue la de añadir claves foráneas. Un contacto puede tener varios teléfonos mientras que un teléfono solo pertenece a un contacto. Por eso, en la creación de la tabla teléfonos se ha especificado un campo id_contacto para que haga de clave foránea. Es aquí, en la última migración donde lo especificamos «modificando» la tabla telefonos.
Mi recomendación siempre es que las «alter table» sean las últimas migraciones ya que cuando las compilemos, Laravel leerá desde la primera a la última y no puede haber incongruencia en las sentencias SQL (primero los create y luego los alter):
class AddForeignKeyContactos extends Migration { public function up() { Schema::table('telefonos', function (Blueprint $table) { $table->foreign('id_contacto') ->references('id') ->on('contactos') ->onDelete('cascade'); }); } public function down() { Schema::table('telefonos', function (Blueprint $table) { $table->dropForeign('id_contacto'); $table->dropColumn('telefonos'); }); } }
Al ejecutar el comando migrate debería habernos creado toda la estructura de tablas en la base de datos.
php artisan migrate
En el caso de haber cometido errores durante la creación de los esquemas, se pueden utilizar estos dos comandos para revocar la última migración o todas las migraciones respectivamente:
php artisan migrate:rollback php artisan migrate:reset
Seeders
Con los seeders, Laravel nos permite rellenar con campos aleatorios nuestras tablas sin necesidad de ir uno por uno.
También son archivos PHP que se ubican en /database/seeds/ y que se crean de manera muy parecida a las migraciones:
php artisan make:seeder ContactosSeeder
Una vez creada la clase que extiende de Seeder, hace falta un generador, este se llama Faker. Implementado desde la versión 5.1 de Laravel e insertado en el archivo composer.json la instalación de Laravel de este manual ya cuenta con él para utilizarlo.
El archivo seeder creado cuenta con una función llamada RUN. Importante antes de poder trabajar con Faker, es agregarlo en la cabecera del documento con use. Debería quedarnos así:
use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Faker\Factory as Faker; class ContactosSeeder extends Seeder { public function run(){ // puntero para recorrer Faker $handle = Faker::create(); for ($i=0; $i<10; $i++) { DB::table('contactos')->insert([ 'nombre' => $handle->firstName, 'apellidos' => $handle->lastName, 'created_at' => date('Y-m-d'), 'updated_at' => date('Y-m-d') ]); } } }
Dentro de la función de ejecución observamos que se debe crear un objeto Faker que se convertirá en nuestro puntero para generar sus nombres.
Abrimos el bucle hasta 10 unidades y le decimos: En la tabla ‘contactos’ inserte un array de datos. Un nombre generado por Faker con una propiedad llamada ‘firstName’ (hay muchos más en este directorio que nos podrían resultar interesantes). Para el apellido se usa la llamada a ‘lastName’. Y grabamos por último las fechas. Recordemos que el identificador es auto numérico y se genera solo. Por eso no aparece.
Pero no acaba aquí la cosa. Por defecto tenemos creado también en el directorio /seeds un archivo PHP llamado DatabaseSeeder.php donde se listarán todos los seeders que queremos generar.
use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { // $this->call(UsersTableSeeder::class); $this->call(ContactosSeeder::class); } }
Ejecutando en una consola el siguiente comando se lanzará la ejecución para generar las semillas en la base de datos:
php artisan db:seed