PHP

Boas Práticas de Laravel Migrations e Seeders na Prática para Times Ágeis

9 min de leitura

Boas Práticas de Laravel Migrations e Seeders na Prática para Times Ágeis

Entendendo Migrations: Versionamento do Seu Banco de Dados Migrations no Laravel funcionam como um sistema de controle de versão para sua estrutura de banco de dados. Em vez de criar tabelas manualmente via SQL, você define-as através de código PHP que pode ser rastreado, compartilhado e revertido. Isso é fundamental em projetos colaborativos onde múltiplos desenvolvedores precisam manter o esquema do banco sincronizado. Uma migration é basicamente uma classe que descreve alterações no banco de dados. Ela contém dois métodos: (o que fazer) e (como desfazer). Laravel cria um arquivo com timestamp automático para garantir que as migrações rodem sempre na ordem correta. Aqui você vê a estrutura típica: o método cria a tabela com suas colunas, e a remove. O timestamp no nome do arquivo garante que esta migration rode antes de uma criada depois. Use para executar todas as migrações pendentes e para desfazer a última batida de migrações. Criando Migrations com Gerador O Laravel oferece um comando

<h2>Entendendo Migrations: Versionamento do Seu Banco de Dados</h2>

<p>Migrations no Laravel funcionam como um sistema de controle de versão para sua estrutura de banco de dados. Em vez de criar tabelas manualmente via SQL, você define-as através de código PHP que pode ser rastreado, compartilhado e revertido. Isso é fundamental em projetos colaborativos onde múltiplos desenvolvedores precisam manter o esquema do banco sincronizado.</p>

<p>Uma migration é basicamente uma classe que descreve alterações no banco de dados. Ela contém dois métodos: <code>up()</code> (o que fazer) e <code>down()</code> (como desfazer). Laravel cria um arquivo com timestamp automático para garantir que as migrações rodem sempre na ordem correta.</p>

<pre><code class="language-php">// database/migrations/2024_01_15_100000_create_users_table.php

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration

{

public function up()

{

Schema::create(&#039;users&#039;, function (Blueprint $table) {

$table-&gt;id();

$table-&gt;string(&#039;name&#039;);

$table-&gt;string(&#039;email&#039;)-&gt;unique();

$table-&gt;timestamp(&#039;email_verified_at&#039;)-&gt;nullable();

$table-&gt;string(&#039;password&#039;);

$table-&gt;rememberToken();

$table-&gt;timestamps();

});

}

public function down()

{

Schema::dropIfExists(&#039;users&#039;);

}

}</code></pre>

<p>Aqui você vê a estrutura típica: o método <code>up()</code> cria a tabela com suas colunas, e <code>down()</code> a remove. O timestamp no nome do arquivo garante que esta migration rode antes de uma criada depois. Use <code>php artisan migrate</code> para executar todas as migrações pendentes e <code>php artisan migrate:rollback</code> para desfazer a última batida de migrações.</p>

<h3>Criando Migrations com Gerador</h3>

<p>O Laravel oferece um comando que cria migrations com boilerplate pronto. Para criar uma nova tabela, use:</p>

<pre><code class="language-bash">php artisan make:migration create_posts_table --create=posts</code></pre>

<p>Se você quer alterar uma tabela existente:</p>

<pre><code class="language-bash">php artisan make:migration add_status_to_users_table --table=users</code></pre>

<p>No segundo caso, o método <code>up()</code> vem com a estrutura para modificação:</p>

<pre><code class="language-php">public function up()

{

Schema::table(&#039;users&#039;, function (Blueprint $table) {

$table-&gt;string(&#039;status&#039;)-&gt;default(&#039;active&#039;);

$table-&gt;softDeletes();

});

}</code></pre>

<p>Repare que usamos <code>Schema::table()</code> para alterar tabelas existentes, enquanto <code>Schema::create()</code> é para criar novas. Detalhes como este fazem diferença real em produção.</p>

<h2>Seeders: Populando Dados de Forma Inteligente</h2>

<p>Se migrations definem a estrutura, seeders definem os dados iniciais. Um seeder é uma classe que insere registros no banco durante desenvolvimento ou setup inicial. Isso evita que você insira dados manualmente ou através de SQL puro.</p>

<p>Crie um seeder com <code>php artisan make:seeder PostSeeder</code>. Laravel gera um arquivo em <code>database/seeders/PostSeeder.php</code>:</p>

<pre><code class="language-php">namespace Database\Seeders;

use App\Models\Post;

use Illuminate\Database\Seeder;

class PostSeeder extends Seeder

{

public function run()

{

Post::create([

&#039;title&#039; =&gt; &#039;Primeiro Post&#039;,

&#039;content&#039; =&gt; &#039;Conteúdo do post...&#039;,

&#039;author_id&#039; =&gt; 1,

]);

Post::create([

&#039;title&#039; =&gt; &#039;Segundo Post&#039;,

&#039;content&#039; =&gt; &#039;Mais conteúdo...&#039;,

&#039;author_id&#039; =&gt; 1,

]);

}

}</code></pre>

<h3>Factories: Gerando Dados em Massa</h3>

<p>Para dados de teste ou desenvolvimento, factories são muito mais práticas que inserir registros um por um. Uma factory define como gerar dados fictícios realistas usando a biblioteca Faker:</p>

<pre><code class="language-php">// database/factories/PostFactory.php

namespace Database\Factories;

use App\Models\Post;

use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory

{

protected $model = Post::class;

public function definition()

{

return [

&#039;title&#039; =&gt; $this-&gt;faker-&gt;sentence(5),

&#039;content&#039; =&gt; $this-&gt;faker-&gt;paragraph(4),

&#039;author_id&#039; =&gt; \App\Models\User::factory(),

&#039;published_at&#039; =&gt; $this-&gt;faker-&gt;optional()-&gt;dateTime(),

];

}

}</code></pre>

<p>Agora seu seeder pode usar a factory para gerar múltiplos registros:</p>

<pre><code class="language-php">public function run()

{

// Cria 50 posts com dados realistas

Post::factory(50)-&gt;create();

// Ou criar com relações

Post::factory(10)-&gt;for(User::first())-&gt;create();

}</code></pre>

<p>Isso economiza linhas de código e torna dados de teste mais realistas.</p>

<h3>Executando Seeders de Forma Organizada</h3>

<p>O DatabaseSeeder funciona como maestro que orquestra todos os seus seeders:</p>

<pre><code class="language-php">// database/seeders/DatabaseSeeder.php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder

{

public function run()

{

$this-&gt;call([

UserSeeder::class,

PostSeeder::class,

CommentSeeder::class,

]);

}

}</code></pre>

<p>Execute tudo com um único comando:</p>

<pre><code class="language-bash">php artisan db:seed</code></pre>

<p>Para rodar um seeder específico:</p>

<pre><code class="language-bash">php artisan db:seed --class=PostSeeder</code></pre>

<p>Uma abordagem profissional combina migrations com seeders no setup completo:</p>

<pre><code class="language-bash">php artisan migrate:fresh --seed</code></pre>

<p>Este comando apaga tudo e reconstrói o banco do zero, rodando migrations e seeders. Perfeito para desenvolvimento local ou ambientes de teste.</p>

<h2>Boas Práticas e Casos Reais</h2>

<p>Em projetos reais, você terá migrações complexas com relacionamentos, índices e constraints. Sempre crie relacionamentos corretamente:</p>

<pre><code class="language-php">Schema::create(&#039;posts&#039;, function (Blueprint $table) {

$table-&gt;id();

$table-&gt;string(&#039;title&#039;);

$table-&gt;text(&#039;content&#039;);

$table-&gt;foreignId(&#039;user_id&#039;)-&gt;constrained(&#039;users&#039;)-&gt;onDelete(&#039;cascade&#039;);

$table-&gt;timestamps();

$table-&gt;index(&#039;user_id&#039;);

$table-&gt;fullText(&#039;title&#039;, &#039;content&#039;); // para busca

});</code></pre>

<p>Use <code>foreignId()</code> e <code>constrained()</code> para criar foreign keys com integridade referencial. O <code>onDelete(&#039;cascade&#039;)</code> garante que posts sejam deletados se o usuário for deletado.</p>

<p>Para dados sensíveis ou padrões em produção, considere separar seeders de desenvolvimento:</p>

<pre><code class="language-bash">php artisan make:seeder --seed=local AdminUserSeeder</code></pre>

<p>Coloque dados reais apenas em seeders específicos, nunca hardcode credenciais. Use variáveis de ambiente quando necessário dados sensíveis.</p>

<h2>Conclusão</h2>

<p>Migrations e seeders são pilares de um workflow profissional em Laravel. <strong>Primeiro ponto</strong>: migrations dão versionamento e reversibilidade ao seu schema — sempre use migrations, nunca SQL direto em produção. <strong>Segundo ponto</strong>: combine seeders com factories para popular dados de forma escalável e mantível. <strong>Terceiro ponto</strong>: organize seu DatabaseSeeder para orquestrar múltiplos seeders em ordem lógica, e sempre teste <code>migrate:fresh --seed</code> antes de fazer deploy.</p>

<p>Domine estes conceitos agora e você terá uma base sólida para trabalhar com Laravel em qualquer escala.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://laravel.com/docs/migrations" target="_blank" rel="noopener noreferrer">Laravel Migrations - Documentação Oficial</a></li>

<li><a href="https://laravel.com/docs/seeding" target="_blank" rel="noopener noreferrer">Laravel Database Seeding - Documentação Oficial</a></li>

<li><a href="https://laravel.com/docs/eloquent-factories" target="_blank" rel="noopener noreferrer">Laravel Model Factories - Documentação Oficial</a></li>

<li><a href="https://github.com/fzaninotto/Faker" target="_blank" rel="noopener noreferrer">Using Faker for Realistic Test Data</a></li>

<li><a href="https://laravel.com/docs/database-testing" target="_blank" rel="noopener noreferrer">Laravel Database Testing Best Practices</a></li>

</ul>

Comentários

Mais em PHP

Upload de Arquivos com PHP: Validação e Segurança na Prática
Upload de Arquivos com PHP: Validação e Segurança na Prática

Upload de Arquivos com PHP: Validação e Segurança Upload de arquivos é uma fu...

Laravel Authentication com Breeze e Sanctum na Prática
Laravel Authentication com Breeze e Sanctum na Prática

Entendendo Laravel Breeze e Sanctum Laravel Breeze é um kit de autenticação m...

Como Usar Autenticação JWT e OAuth 2.0 em APIs PHP em Produção
Como Usar Autenticação JWT e OAuth 2.0 em APIs PHP em Produção

JWT: Fundamentos e Implementação Prática JWT (JSON Web Token) é um padrão abe...