Desenvolvimento

24 out, 2017

Criando migrations e relacionando tabelas com Laravel

Publicidade

Quando nossa equipe inicia um determinado projeto, costumamos nos reunir para discutir sobre a estrutura do banco de dados, como as regras de negócio serão implementadas e os dados serão gravados para tudo funcionar o mais perfeito possível. Desta discussão, já montamos o primeiro modelo de relacionamentos das tabelas no banco de dados. Costuma ser um modelo rápido feito no WorkBench.

Acredito que este processo seja parecido em diversas empresas de desenvolvimento, quando estão iniciando um projeto. Agora apresento algumas facilidades e seguranças que os Migrations do Laravel implementam para a montagem da estrutura do seu banco de dados, assim como seu relacionamento como um todo.

Como exemplo prático, farei uma simulação através da minha plataforma de Hospedagem Cloud, da DialHost. Primeiro, montei este banco que simula o catálogo de produtos de uma loja. Este banco possui os produtos e seu relacionamento com a linha de produtos.

Criando o Migration

O conceito de migration, trazido pelo Laravel, permite o controle de versões e, assim, facilita a modificação e o compartilhamento da estrutura do banco de dados entre equipes. Imagine que você está mexendo em um projeto, em seu ambiente de desenvolvimento. Você cria uma nova coluna em seu banco de dados e continua desenvolvendo seu código normalmente. Sem o migration, seu colega pega seu código e coloca no ambiente de desenvolvimento dele e tenta rodar. É claro que teremos diversos erros disparando na tela deste cara.

Agora, com o migration seu colega de trabalho verá nos registros de versionamento do código que teve uma atualização de arquivos na pasta “migration” e, então, basta ele rodar o comando php artisan migrate que seu banco estará totalmente atualizado.

Para criar um migration, durante o desenvolvimento do código é importante que tenhamos uma configuração de banco de dados. Afinal, no fim das contas os migrations irão produzir um banco de dados.

Para configurá-lo, basta setar as configurações do banco de dados, criado em seu servidor, dentro do arquivo .env que fica na raiz do projeto.

 DB_CONNECTION=mysql
 DB_HOST=127.0.0.1
 DB_PORT=3306
 DB_DATABASE=my_store
 DB_USERNAME=fmv
 DB_PASSWORD=$%SDFFHHJ

Ahhh, quase ia me esquecendo! Se você chegou aqui, mas está perdido em como instalar o Laravel, tenho o primeiro artigo desta série.

Tudo configurado, agora vamos gerar nossas novas classes de migration. Isto tudo será feito através do comando artisan make:migration.

 php artisan make:migration create_product_line --create=product_line
 php artisan make:migration create_product --create=product

Ao final de cada comando, vocês podem ver que adicionei a opção –create. Esta opção permite que eu defina o nome da tabela que eu estou criando. Existem outras opções para este comando que vocês podem ver na documentação completa do Laravel 5.5.

A estrutura da migration é simples. Ela importa as classes Schema, Blueprint e Migration e possui 2 funções:

UP

Esta função é a responsável pela implementação das atualizações do banco, criar uma tabela, atualizar uma coluna etc.

Down

É a função que fará exatamente o inverso da função UP, revertendo seu banco de dados ao estado anterior a esta atualização.

Então, minhas classes ficaram desta forma.

create_product

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class create_product extends Migration
{
public function up() {
Schema::create('product', function (Blueprint $table) {
$table->smallIncrements('id');
$table->string('description')->unique();
$table->string('expiration_date');
$table->decimal('price', 4, 2);
$table->timestamps();
$table->engine = 'InnoDB';
});
}

public function down() {
Schema::drop('product');
}
}

 

create_product_line

 

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class create_product_line extends Migration
{
public function up() {
Schema::create('product_line', function (Blueprint $table) {
$table->smallIncrements('id');
$table->string('description')->unique();
$table->timestamps();
$table->engine = 'InnoDB';
});
}

public function down() {
Schema::drop('product');
}
}

Acima, você vai ver que existe uma definição que não estava em meu diagrama. $table->timestamps(); Isto é um padrão do Eloquent do Laravel para controlar quando um dado é criado e atualizado.

Outra definição do diagrama porém, não foi incluída de propósito. Fiz isto para chegar finalmente ao objetivo deste artigo. Os relacionamentos entre as tabelas:

Relacionando tabelas

Com o migration é possível criar foreign keys e definir o relacionamento entre as tabelas do seu banco de dados. Este relacionamento cria restrições que protegem a integridade dos dados suas tabelas.

Para criar este relacionamento é bem simples. Voltemos ao nosso exemplo no arquivo create_product:

...
Schema::create('product', function (Blueprint $table) {
$table->smallIncrements('id');
$table->foreign('product_line_id')->references('id')->on('product_line');
$table->string('description')->unique();
...

Traduzindo a linha nova, temos uma Foreign key que referencia à coluna “id” na tabela “product_line”.

Além disto, é possível adicionar restrições para qualquer ação de atualização (onUpdate) e exclusão (onDelete) de registros dentro da tabela. Neste caso, tratarei para que sempre que houver a exclusão de uma linha de produtos, este perca a referência com a tabela product_line (setar como nulo).

...
Schema::create('product', function (Blueprint $table) {
$table->smallIncrements('id');
$table->foreign('product_line_id')
->unsigned()
->nullable()
->references('id')
->on('product_line')
->onDelete('set null');
$table->string('description')->unique();
...

Desta forma, eu permito que uma linha de produto seja excluída. Claro que aqui o produto ficará orfão de uma linha de produto. Mas, por enquanto, estamos apenas trabalhando as regras do banco.

Removendo um relacionamento

Apenas para concluir… Se quiser remover o relacionamento criado, isto é possível utilizando o método dropForeign.

$table->dropForeign(['product_line_id']);

Agora que o migration está completo, o próximo passo será definir as models. Mas, este fica para o próximo artigo.