Trabalhando com seeds no Laravel 5



O workflow do Laravel é incrível, há muitos recursos a nossa disposição de modo a tornar o desenvolvimento dos seus projetos simples e divertido.

Porém os marinheiros de primeira viajem podem se assustar com alguns recursos, e é sobre um deles que vou falar dessa vez: Seeds

Alguns conhecem seeds como “data dummy”, “dados de teste” ou até mesmo como “carga inicial”. Todos os termos são válidos, pois o seed pode ser usado de duas maneiras: gerar dados fictícios e gerar a carga inicial de dados

Dados fictícios

Uma das tarefas mais corriqueiras na maioria dos sistemas é o CRUD (Create Read ou Retrieve, Update e Delete).
Quando estamos trabalhando com migrations muitas vezes temos que refazer a instalação, ou até mesmo quando distribuímos o projeto entre os membros da equipe, entramos em um mini dilema. Ter que fazer todos os cadastros na “munheca” ou distribuir um *.sql (medo!)

Carga inicial

Muitas vezes criamos sistemas que precisam ser instalados em muitos lugares, isso ocorre por diversos motivos.
Nessa carga inicial podemos precisar de:

  • Usuários administradores
  • Categorias base
  • Qualquer outro dado que tenha se ser inserido a cada instalação da aplicação
É nesse momento que o seed entra!
Para automatizar a inserção de registros nas tabelas do nosso projeto.

Criando seu primeiro seed

Antes de tudo temos que entender a classe DatabaseSeeder, que fica em databases/seed/

Como podem ver o funcionamento dela é muito simples, você diz quais as classes (seeds) serão executados e em qual ordem, pois alguns dados dependem de outros para serem gerados.


A SEMENTE!

Agora podemos criar nosso primeiro seed, que é apenas uma classe simples, mas que possui o método run

Como eu disse bem simples!

  • Apago os dados existentes da tabela (users)
  • Crio dois usuário com dados “fixos” eles são os usuários que eu quero sempre ter na minha carga inicial.
  • Uso um for para cadastrar uma série de usuários com dados dummy. Esse processo pode ser ainda mais fácil usando pacotes como TestDummy e Faker

Seeds mais “elaborados”

Você pode elaborar e organizar seus seeds conforme sua necessidade, como eu disse antes alguns dados dependem de outros para serem criados. Para exemplificar isso vou criar um seed para o pacote de ACL da comunidade Laravel Brasil o de Defender. Para isso vou criar mais um seed e modificar um pouco o seed anterior. Vou também passar a usar o pacote Faker para deixar o seed mais interessante.

Defender

Em DefenderSeeder.php eu apago todos os dados de roles e permissions, crio roles e permissions, para depois “adicionar” as permissions criadas as roles criadas.
Ainda uso collections para facilitar a manipulação, cortesia do nosso amigo Vedovelli.

Users

Agora o nosso seed de usuários ficou bem mais elaborada.
Eu ainda deleto todos os usuários antes, e crio meu usuários fixos e com dados falsos, mas agora uso o Faker para me disponibilizar dados mais ‘reais’ além de alguns facilitadores.
Agora eu carrego todos os roles em uma variável para não precisar fazer muitas consultas no banco de dados, e continuo usando os métodos de collections para manipular a lista de roles.


Algumas vezes seu seed pode dar erro devida a existência ou ausência de FKs do banco de dados. Há também o perigo de rodar o seed em ambiente de produção.
Para esses problemas deixo a dica abaixo:

Usem esse comando com moderação, se algo der errado seu banco de dados pode parar de avaliar suas FKs

Produzir este tipo de post é particularmente complicado e trabalhoso, pois exige código e conceito. E no caso do seed a minha solução pode não ser a que se encaixa no sua necessidade, o importante mesmo é entender como os seeds funcionam.

Seja como for espero ter esclarecido as duvidas de quem não sabe usar seeds e quem já sabe, talvez tenha algumas ideias novas.

Tudo que eu apresentei aqui funciona no Laravel 4, com exceção do Defender, alguns comandos de collecions e o comando de detecção de environment, que no L4 é diferente

Queria poder dar mais alguns exemplos de como criar registros com melhor performance usando QueryBuilder no lugar do Eloquent, quem sabe na próxima.