Database Seed - MarketPlace - #2
Published: 2022-10-07 01:25:29

Esta é a segunda parte do artigo sobre criação de dados de forma relacional para testar mais consistentemente sua aplicação.

Na [primeira parte](https://dev.to/marciopolicarpo/database-seed-marketplace-1-1226) fiz uma breve introdução sobre a proposta do projeto.

Agora vamos iniciar o desenvolvimento das migrações. 

---

### Migração

Migrações, a grosso modo, são uma maneira de versionar o schema de um banco de dados. 

Embora boa parte dos frameworks atuais possua uma forma de gerenciar migrações, ela não é mandatória para o desenvolvimento de um projeto.

Aliás é comum vermos migrações em projetos que estão começando, por se enquadrarem mais facilmente em metodologias e boas práticas de desenvolvimento. 

Entretanto isso não significa que projetos legados não possam ter o schema versionado. Ocorre que nestes casos (projetos legados) há pouca ou às vezes nenhuma documentação disponível sobre o projeto, dificultando significativamente esta tarefa.

---

### Projeto

O projeto proposto para esta série de artigos será uma aplicação Laravel. Por essa razão, vou presumir que você, leitor, já tenha conhecimento prévio nesse framework.

Caso este não seja o seu cenário, sugiro dar uma lida [neste artigo](https://dev.to/marciopolicarpo/multi-banco-de-dados-em-aplicacoes-laravel-2ob8) onde explico como configurar a conexão com um banco de dados, além de outros detalhes.

---

Abra o terminal de sua preferência e acesse a pasta onde o projeto será criado.

A partir desta pasta digite o seguinte:

```
composer create-project laravel/laravel fake-data
```

O tempo para conclusão desta tarefa varia de acordo com a configuração da máquina e a conexão com a internet.

Concluída esta etapa, ainda no terminal, acesse a pasta do projeto para criar as migrações, processo este que é realizado através do seguinte comando:

```php
php artisan make:migration <nome_da_migracao> [opções]
```

_OBS.: É possível criar com um único comando a migração, a 'controller', o modelo e a 'factory'. Esta abordagem não será adotada para possibilitar explicações mais detalhadas em cada fase_.

---

### 'Mão na massa'

:warning: A sequência de criação das migrações é de extrema relevância porque serão executadas no banco de dados na ordem em que forem criadas.

Com isso em mente daremos início à criação das migrações sendo que para cada uma delas vou passar o comando que deve ser executado no terminal e logo em seguida, como a classe deverá ficar. 

Para alterar a classe utilize um editor de código no qual você já esteja habituado. Estou utilizando o [VSCode](https://code.visualstudio.com/download) por ser pequeno e versátil.

---

> Customers

No terminal, dentro do diretório raiz da aplicação, digite o seguinte:

```php
php artisan make:migration create_customers_table
```

Assim que o comando for concluído, você notará que um novo arquivo foi adicionado à pasta **\database\migrations**. O nome desse arquivo é composto pelo ano, mês, dia, hora, minuto e segundo da sua criação, seguido pelo nome que demos no comando informado no terminal.

Essa padronização garante que cada migração tenha um nome único e servirá de índice quando as tabelas forem criadas no banco de dados.

Portanto, não se preocupe se os nomes dos arquivos ficarem diferentes daqueles que listarei a seguir. :relaxed:

Quando criei a migração o arquivo recebeu este nome:
`2022_09_29_215131_create_customers_table.php`

E o caminho completo dentro da aplicação ficou assim:
`\database\migrations\2022_09_29_215131_create_customers_table.php`

Edite o arquivo substituindo todo conteúdo pelo listado a seguir:

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained();
            $table->string('last_name');
            $table->string('first_name');
            $table->string('email')->nullable();
            $table->string('phone', 30)->nullable();
            $table->string('street');
            $table->string('city');
            $table->string('building_number', 30);
            $table->string('country');
            $table->string('post_code');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('customers');
    }
};
```

---

> Shops

Repetindo os passos executados na criação da migração anterior...

```php
php artisan make:migration create_shops_table
```

...obtemos um novo arquivo que, no meu caso, será este:

`\database\migrations\2022_09_29_215237_create_shops_table.php`

Agora vamos editá-lo, substituindo o conteúdo pelo mostrado logo abaixo:

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('shops', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained();
            $table->string('name');
            $table->string('email');
            $table->string('address');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('shops');
    }
};

```

---

> Produtcs

Novamente no terminal, digitaremos o seguinte comando:

```php
php artisan make:migration create_products_table
```

No meu caso, o arquivo terá este nome...

`\database\migrations\2022_09_29_215336_create_products_table.php`

...e o conteúdo substituído pelo mostrado a seguir:

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->foreignId('shop_id')->constrained();
            $table->string('description');
            $table->decimal('price', 8, 2);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
};

```

---

> Invoices

Mais uma vez no terminal...

```
php artisan make:migration create_invoices_table
```

...gerando este arquivo...

`\database\migrations\2022_09_29_215415_create_invoices_table.php`

...e como deve ficar seu conteúdo:

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('invoices', function (Blueprint $table) {
            $table->id();
            $table->date('issue_date');
            $table->foreignId('customer_id')->constrained();
            $table->foreignId('shop_id')->constrained();
            $table->string('delivery_address');
            $table->string('delivery_city');
            $table->string('delivery_country');
            $table->string('delivery_post_code');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('invoices');
    }
};

```

---

> Invoice items

Por fim, a última migração...

```php
php artisan make:migration create_invoice_items_table
```

...recebendo este nome de arquivo...

`\database\migrations\2022_09_29_215449_create_invoice_items_table.php`

...e este conteúdo:

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('invoice_items', function (Blueprint $table) {
            $table->id();
            $table->foreignId('invoice_id')->constrained();
            $table->foreignId('product_id')->constrained();
            $table->smallInteger('amount');
            $table->decimal('value', 8, 2);
            $table->decimal('tax', 8, 2);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('invoice_items');
    }
};

```

---

### Conclusão

Nesta parte do artigo criamos as migrações implementando o relacionamento entre as tabelas, que foi feito através da instrução `$table->foreignId('<coluna>')->constrained();`.

Para efeitos didáticos, vou exemplificar o relacionamento que existe entre a loja e um produto.

Primeiro, criamos uma chave primária na tabela de lojas com o comando `$table->id();`.

Em seguida, criamos a chave estrangeira na tabela de produtos com o comando `$table->foreignId('shop_id')->constrained();`.

Ao executarmos a migração, o Laravel se encarregará de criar os relacionamentos corretamente no banco de dados configurado.

Fácil, não?!:wink:

---

Por enquanto é isso. 

Até a próxima parte.
:sunglasses: