Buscar

v 1 0 0-livro-laravel-database-o-guia-definitivo

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 167 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 167 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 167 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Ementa 
Ementa
Introdução ao Livro
Nota
Ambiente
Suporte: Como tirar as dúvidas?
Versão Atualizada
Erros
Quem Sou Eu?
Prefácio
Database
Introdução
Configuração
Configurando o SQLite
Configurando MySQL
Várias Conexões
Migrations
Gerando Arquivos de Migrations
Padrão de Tabelas
Estrutura
Rodar Migrations
Reverter Migrations
Rollback e Migration
Deletar e Criar Novamente
Tabelas
Criando Novas Tabelas
Renomear e Deletar Tabelas
Colunas
Modificar Colunas
Índices
Criando índices
Tipos de índices disponíveis
Tamanho índices (MySQL / MariaDB)
Renomear índices
Deletar índices
Chave estrangeira (Foreign Key)
Deletar chave estrangeira (foreign key)
Database: Seeding
Introdução
Criando uma Seeder
Definindo um Usuário Padrão
Rodar Seeders
Factories
Relacionamento de tabelas
Eloquent
Introdução
Criar Models
Padrões
af://n0
Nomes de Tabelas
Chave Primária
Timestamps
Models
Listando os registros
Filtros
Inserir
Mass Assignment
Editar
Deletar
Filtrar e excluir
Excluir pela chave primária
Soft Deleting
Utilizando o Recurso de Soft Deleting
Incluindo Registros Deletados
Recuperando Apenas os Deletados
Restaurando
Deletar Permanentemente
Outras Opções
firstOrCreate
firstOrNew
updateOrCreate
Comparando Models
Eloquent Relacionamentos de Tabelas
Eloquent Relationships One to One
One to One Inverso
Inserir
Simplificando Consultas
Eloquent Relationships One to Many
Definir o relacionamento One to Many
Simplificando Consultas
Inserindo avaliações
Editar avaliação
Eloquent Relationships Many to One
Eloquent - Many to Many
Criar os Relacionamentos
Exibindo os registros relacionados
Recuperar dados tabela pivô
Timestamps
Vincular registros Many to Many
Toggle
Atualizar Registro Tabela Pivô
Eloquent Relationships - Eager Loading
Nested Eager Loading
Colunas Especificas
Constraining Eager Loads
Lazy Eager Loading
Eloquent Relationships - Touching Parent Timestamps
Eloquent Collections
Collections disponíveis
all()
get()
count()
avg()
average()
max()
min()
median()
first()
firstWhere()
last()
has()
prepend()
push()
put()
pop()
where()
whereStrict()
whereIn()
whereInStrict()
whereNotIn()
whereNotInStrict()
sort()
sortBy()
sortByDesc()
groupBy()
Eloquent Mutators
Data Mutators
Eloquent Escopos
Locais
Dinâmicos
Globais
Aplicando Escopo Global
Globais Anônimos
Remover Escopos Globais
Remover Todos os Escopos Globais
Eloquent Eventos
Introdução
Exemplo Prático
Observadores
Database - Query Builder
Introdução
Buscando Registros no Banco de Dados
Recuperando todos os registros
Recuperando um Registro
Recuperar Valor Específico de uma Coluna
Recuperando os Valores de Algumas Colunas
Consultas Agregadas
Expressões SQL brutas
Métodos brutos
selectRaw
whereRaw / orWhereRaw
havingRaw / orHavingRaw
orderByRaw
Parâmetros nomeados
Joins
Inner Join
Left Join
Cross Join
Joins Avançado
Sub-Query Joins (sub consulta)
Unions
Cláusulas Where
where
orWhere
whereBetween
whereNotBetween
whereIn
whereNotIn
whereNull
whereNotNull
whereDate
whereMonth
whereDay
whereYear
whereTime
whereColumn
Agrupamento de Parâmetros
whereExists
Where JSON
Inserir JSON
Filtrar JSON
whereJsonContains
whereJsonLength
Cláusulas condicionais
Ordenar Consultas
Ordenar por mais recentes
Ordenar por mais antigos
Ordenar aleatóriamente
groupBy / having
Paginação manual
Inserir
Inserir json
Atualizar
Atualizar JSON
Incrementar
Decrementar
Deletar
Outros Assuntos
Consultas SQL brutas (Raw SQL)
Selecionar
Inserir
Editar
Deletar
Executando uma declaração geral
Transações de banco de dados
Introdução
Deadlocks
Manual
Paginação
Query Builder
Eloquent
Paginação Simples
Customizar URL
Anexando Parâmetros
Paginar APIs ( JSON)
Customizar Paginação
Métodos disponíveis
Query Builder vs Eloquent ORM vs Raw SQL
Eloquent
Query Builder
Raw SQL
Desempenho
Concluindo
O que vem agora?
Ao adquirir este livro pelas vias legais você recebeu os dados de acesso a nossa plataforma ead,
diretamente no seu e-mail (confere na caixa de SPAMs).
Introdução ao Livro 
Nota 
Primeiramente, deixo uma nota sobre a pirataria. Infelizmente nem todos os profissionais tem seus valores
bem definidos e um caráter fortalecido para cumprir com os deveres morais como cidadão de bem. Portanto,
se comprou/baixou este livro fora de algum site/pagina/canal NÃO vinculado à EspecializaTi, por favor, nos
notifique o quanto antes, para que possamos tomar as medidas necessários contra a pirataria (meu contato
pessoal e direto é: carlos@especializati.com.br).
 
 
Ambiente 
Criar um ambiente de desenvolvimento para o PHP é um desafio, especialmente porque temos diversas
opções, e em alguns sistemas operacionais o desafio é ainda maior. Portanto, para criar algo mais dinâmico e
visual, a primeira etapa deste livro está disponível na plataforma ead, logo o primeiro passo é criar o seu
ambiente para trabalhar com o Laravel seguindo os passos citados lá.
Nesse curso inicial além de criar o ambiente mostro como realizar os testes práticos do livro, como dá os seus
primeiros passo, enfim, tudo o que precisa para tirar o máximo proveito deste livro está descrito lá.
 
 
Suporte: Como tirar as dúvidas? 
Acho muito interessante a ideia de comprar um livro técnico (como este) e poder contar com o suporte do
autor do livro para aplicar os exemplos práticos, porque dessa forma torna a leitura mais agradável e evita
perder tempo com eventuais problemas. Enfim, toda e qualquer dúvida que você tiver que esteja relacionada
com o tema deste livro basta postar na plataforma ead, que responderei o mais rápido possível. Conta
comigo!
 
 
Versão Atualizada 
Se tiver um bom tempo que já baixou este livro sugiro que baixe a versão atualizada na plataforma ead,
porque este livro estará sempre recebendo atualizações e correções de erros, fazendo assim você sempre
terá acesso as atualizações deste livro.
af://n4
af://n5
mailto:carlos@especializati.com
af://n9
af://n16
af://n20
 
 
Erros 
Esse livro ainda está na sua primeira edição, como não usei nenhuma editora para publicar todo o processo
de escrita, correção de erros e etc ficou em minhas mãos, portanto, caso encontre QUALQUER erro
ortográfico, ou qualquer tipo de erro, ou algo que pode ser melhorado, por favor, me envie imediatamente
para o meu e-mail: carlos@especializati.com.br
 
 
Quem Sou Eu? 
Meu nome é Carlos Ferreira, atuo com desenvolvimento de sistemas web/mobile há 9 anos, e desde 2014
estou ensinando profissionais como obter os melhores resultados possíveis com o Laravel. Já ajudei milhares
de profissionais em todo o mundo. Meu canal do YouTube (segundo a última contagem) já ultrapassou mais
1.419.960 de visualizações, e 90% de todo o conteúdo é Laravel.
Possuo algumas certificações: Comptia Linux +, LPI, Novell Certification.
 
 
Prefácio 
O Laravel é um framework que já não precisa provar mais nada, já está muito conceituado e amplamente
aceito, e cada dia que passa sua popularidade aumenta cada vez mais e mais. É muito comum ver
grandes/pequenas/médias empresas adotarem o Laravel também. Já perdi as contas de quantas vezes
empresas me procuraram para ter consultoria porque iriam migrar velhos sistemas para o Laravel.
Essa popularidade toda do Laravel não é atoa, muito menos mera coincidência, o Laravel é uma framework
que faz por merecer todos os seus resultados, possui todos os méritos. As comunidades do Laravel são
extremamente ativas, e amigáveis em contribuir e ajudar, isso sem dúvidas é mais um grande diferencial.
Os profissionais envolvidos com o framework fazem justiça ao Laravel, porque são extremamente
competentes, e tudo isso é refletido no framework. Se você tiver curiosidade observe o core do Laravel, e veja
a qualidade do código e das implementações, realmente é tudo muito bem pensado. Sinceramente, nunca vi
um projeto com um nível de capricho tão grande como este, cada detalho foi pensado e planejado para obter
o melhor resultado possível.
Neste livro descrevo os recursos de manipulação de banco de dados do Laravel, e já dá para ter ideia o
quanto o Laravel é poderoso,e ao mesmo tempo respeita a sua principal característica, que é ser simples.
 
 
af://n24
mailto:carlos@especializati.com
af://n28
af://n33
Recurso Descrição
default
(String) É a conexão padrão que será usada para conectar a aplicação ao banco de
dados
connections (Array) Dados de acesso a todas as conexões
migrations
(String) Nome da tabela que controla os arquivos de migrations que já foram executados
em nossa aplicação (Mais detalhes no capitulo sobre migrations)
redis
(Array) Dados de configuração do Redis (O Redis é um armazenamento de chave e valor
de código aberto, rápido e avançado), o Redis pode ser utilizado para trabalhar com
cache.
 
 
Database 
 
Introdução 
Um dos pontos fortes do Laravel é justamente sua capacidade de interação com bancos de dados, além de
possuir recursos avançados, provê métodos extremamente simples para lidar com diferentes bancos de
dados. Atualmente, o Laravel possui suporte para quatro bancos de dados, sendo eles:
MySQL
PostgreSQL
SQLite
SQL Server
 
 
Configuração 
As configurações de database ficam localizadas no arquivo config/database.php . Neste arquivos podemos
definir todas as conexões, e também devemos definir qual é a conexão padrão.
Antes de continuar falando mais sobre as configurações é importante entendermos todos as opções
disponíveis no arquivo de configuração config/database.php .
 
 
 
af://n43
af://n45
af://n58
af://n80
NOTA: Helpers são funções globais disponíveis em todos os locais da aplicação Laravel, essas funções
(conhecidas como helpers) são extremamente úteis, e provem recursos que facilitam o nosso
desenvolvimento com o framework.
NOTA: O Helper env() faz a leitura de variáveis de ambiente definidas no arquivo .env, essa função
recebe dois argumentos, o primeiro é o nome da variável que será feito a leitura no arquivo .env, e o
segundo argumento é o valor padrão caso essa variável não exista ou esteja com o valor em branco.
Configurando o SQLite 
Caso o banco de dados que for utilizar seja o SQLite o primeiro passo é criar o arquivo que será utilizado para
armazenar os dados, para isso rode o comando:
Uma vez que já temos o arquivo que armazenará os dados da nossa aplicação o próximo passo é informar no
arquivo config/database.php que o banco de dados que iremos trabalhar é o SQLite, portanto precisamos
alterar a conexão padrão para sqlite :
Ou, também podemos deixar que o Helper env() leia o arquivo .env, neste caso podemos deixar no arquivo
config/database.php assim:
E no arquivo .env precisamos alterar a variável de ambiente DB_CONNECTION para sqlite
 
 
Agora que já definimos que o nosso banco de dados será o SQLite no arquivo config/database.php , no
array connections precisamos atualizar os dados de acesso ao banco:
touch database/database.sqlite
'default' => 'sqlite'
'default' => env('DB_CONNECTION', 'mysql'),
DB_CONNECTION=sqlite
'sqlite' => [
    'driver' => 'sqlite',
    'database' => env('DB_DATABASE', database_path('database.sqlite')),
    'prefix' => '',
    'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
af://n80
Configuração Descrição
driver (String) Drive que o PDO utiliza para acessar bases de dados SQLite.
database
(String) Path (caminho) onde está localizado o arquivo que será utilizado para
armazenar os dados (os registros). O Helper database_path() aponta
justamente para o diretório database/ da aplicação.
prefix
(String) Caso suas tabelas possuam algum prefixo (semelhante ao
Wordpress: wp_) é possível setar qual é o prefixo utilizado em suas tabelas.
foreign_key_constraints
(Boolean) Restrições de chave estrangeira (foreign key). Essa configuração
ajuda a manter a integridade de dados relacionais.
 
 
 
Configurando MySQL 
Caso o banco de dados que for utilizar seja o MySQL o primeiro passo é informar que a conexão defalt
(padrão) é mysql, portanto, no arquivo config/database.php em default vamos definir a conexão como
mysql:
No arquivo .env:
 
Essa configuração vai fazer a leitura do array mysql dentro de connections no arquivo de configuração
config/database.php :
'default' => env('DB_CONNECTION', 'mysql'),
DB_CONNECTION=mysql
'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' => '',
    'prefix_indexes' => true,
    'strict' => true,
    'engine' => null,
af://n115
Configuração Descrição
driver (String) Drive que o PDO utiliza para acessar bases de dados MySQL.
host (String) Endereço de IP ou nome do host com a base de dados MySQL
port (Int) Porta que está rodando o banco de dados.
database (String) Nome do banco de dados.
username (String) Usuário de acesso ao banco de dados
password (Any) Senha de acesso ao banco de dados
charset (String) charset de condificação de caracteres
collation
(String) Collation (Colação) nada mais é que a codificação de caracteres existente no
banco de dados.
prefix
(String) Caso suas tabelas possuam algum prefixo (semelhante ao Wordpress: wp_) é
possível setar qual é o prefixo utilizado em suas tabelas.
Algumas das principais configurações são lidas a partir do helper env(), portanto, precisamos atualizar no
arquivo .env os dados de acesso ao nosso banco de dados MySQL:
 
 
Várias Conexões 
Um recurso muito interessante do Laravel é alternar entre diferentes conexões com uma simplicidade muito
grande, a facade DB permite fazer isso, veja o exemplo:
A conexão precisa estar configurada no arquivo config/database.php e listada em connections , porque a
facade DB vai usar exatamente essas informações para alternar a conexão e fazer o que tiver que ser feito,
seja buscar os registros, inserir novos e etc.
],
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=livro_laravel
DB_USERNAME=root
DB_PASSWORD=root
// Não esquece: use DB;
$users = DB::connection('pgsql')->get();
af://n158
O último exemplo vai fazer a leitura do arquivo de configuração config/database.php e buscar as
informações de conexão em connection de pgsql , ou seja, vai retornar todos os usuários na base de dados
PostgreSQL.
 
'pgsql' => [
    'driver' => 'pgsql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '5432'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
    'prefix_indexes' => true,
    'schema' => 'public',
    'sslmode' => 'prefer',
],
Migrations 
O recurso de Migrations permite gerenciar as tabelas do banco de dados. Com este recurso é possível criar as
tabelas, alterar a estrutura, definir a ordem de criação de cada tabela e fazer relacionamentos entre elas.
Os arquivos de migrations (estrutura das tabelas) ficam em database/migrations/
Grandes empresas possuem departamentos específicos para lidar com bancos de dados, nestes casos os
recursos de migrations não são utilizados, justamente porque existem profissionais para lidar com toda a
responsabilidade de banco de dados, portanto, não fica a cargo do Laravel lidar com a criação das tabelas e
ordem de criação.
Mas, uma das vantagens de trabalhar com o recurso de migrations para criar as tabelas é justamente
centralizar toda a estrutura do banco de dados, trabalhar em equipe neste caso é mais fácil, porque toda a
estrutura do banco de dados está centralizada, e também a ordem das tabelas, relacionamentos e etc, tudo
está organizado e, pode ser compartilhado em equipe.
 
Gerando Arquivos de Migrations 
Para criar um novo arquivo de migration usa o comando do artisan make:migration:
 
Existe um padrão recomendado para gerar arquivos de migrations, o nome do arquivo deve preceder o
prefixo create_ e no finalprecisa ter o nome _table. Se o objetivo é criar um tabela chamada por exemplo
products, o nome do arquivo de migration deve ser create_products_table:
 
Os arquivos de migrations ficam armazenados por default (padrão) em database/migrations/ , cada arquivo
de migration contém no início do nome um timestamps (data e hora), e é justamente esse nome que é usado
para definir a ordem de criação das tabelas. Os arquivos de migrations com o timestamps mais antigo são
gerados primeiramente, seguindo essa ordem.
Mas, tenho uma tabela que precisa vir antes de todas, como ordernar para que ela seja criada
primeiramente? Você pode renomear o timestamps manualmente do arquivo de migration correspondente a
tabela. Mas, uma ação é extremamente importante, sempre que altera algum arquivo de migration
manualmente precisa rodar esse comando para o composer mapear novamente os arquivos de migrations:
 
php artisan make:migration create_tablename_table
php artisan make:migration create_products_table
composer dump-autoload
af://n166
af://n172
Quando cria um arquivo de migration chamado create_products_table por default o mecanismo de
migrations do Laravel entende que a tabela correspondente é products, porém, em alguns casos pode ser
necessário ter uma tabela com um nome diferente do arquivo de migration, para esses casos podemos usar
as options --table ou --create para indicar o nome da tabela, exemplo:
 
No exemplo anterior embora o o arquivo de migration indique que o nome da tabela é products, no exemplo
indicamos que o nome da tabela será produtos, e não products, como é por default.
A opção --create especifica que vamos criar uma nova tabela. A opção --table é usado para alterar a
estrutura default de alguma tabela já existente, ou para adicionar colunas extras.
Outra opção é o --path, essa opção permite especificar um path (caminho/diretório) diferente do default, ou
seja, caso queira uma estrutura de arquivos de migrations personalizada, pode usar a opção --path para
especificar, exemplo:
 
Uma maneira mais prática e popular de criar os arquivos de migrations é combinando o comando que cria o
model (veremos mais sobre Models adiante, não se preocupe). Esse comando já cria o arquivo de model + o
arquivo de migration correspondente:
php artisan make:model Models\\Product -m 
A opção -m que garante que o arquivo de migration create_products_table seja criado também.
 
 
Padrão de Tabelas 
Por padrão o Laravel já trás pré-definido dois arquivos de migrations, um para a tabela de users (usuários) e
outro para a tabela password_resets , que é usada justamente para validar e recuperar a senha do usuário.
Caso a tabela de usuários precise de outras colunas além das padrões, podemos adicionar.
 
 
Estrutura 
As classes de migrations contém básicamente dois métodos, o up e o down. O método up é usado
normalmente para adicionar novas tabelas, com colunas e índices no database. Enquanto o método down é
utilizado para reverter as operações realizadas no método up. Ou seja, se usou o método up para criar um
nova tabela com a sua estrutura de colunas, o método down pode ser usado para deletar a tabela.
php artisan make:migration create_products_table --create=produtos
php artisan make:migration create_roles_table --path=database/migrations
af://n197
af://n202
Vamos criar a estrutura da tabela de products, já com algumas colunas, mais adiante aprenderemos mais
sobre os tipos de colunas possíveis:
use Illuminate\Support\Facades\Schema; 
use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 
 
class CreateProductsTable extends Migration 
{ 
 /** 
 * Run the migrations. 
 * 
 * @return void 
 */ 
 public function up() 
 { 
 Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->string('name'); 
 $table->text('description'); 
 $table->timestamps(); 
 }); 
 } 
 
 
 /** 
 * Reverse the migrations. 
 * 
 * @return void 
 */ 
 public function down() 
 { 
 Schema::drop('products'); 
 } 
 
} 
 
A classe Schema possui o método estático create, que espera dois parâmetro obrigatórios, sendo eles: o
primeiro o nome da tabela, e o segundo uma função de callback para definir a estrutura de colunas da tabela.
Por default a classe de migration traz definido duas colunas:
$table->increments('id'); 
$table->timestamps(); 
 
A primeira definição cria uma coluna chamada id, que será a chave primária da tabela products, e ainda é
autoincrement (o seu valor auto incremental).
$table->increments('id'); 
 
Os padrões do Laravel recomenda que essa coluna se chame id, mas, não há problema algum caso queira
renomear e deixar algum nome "mais coerente", algo como product_id.
A opção timestamps cria duas colunas na tabela products, uma chamada created_at que registra exatamente
e automaticamente o valor do timestamps (data/hora/minutos/segundos) sempre que um novo registro é
inserido. E também cria uma coluna chamada updated_at que registra exatamente e automaticamente o
valor do timestamps (data/hora/minutos/segundos) sempre que o registro é atualizado.
Mais adiante detalharemos um pouco mais sobre as demais colunas, e outras opções.
 
 
 
Rodar Migrations 
Uma vez que definimos a estrutura da nossa tabela no arquivo de migration correspondente o próximo passo
é acessar o projeto pelo terminal e rodar o comando que cria as tabelas, para isso rode o comando:
php artisan migrate 
 
Ao rodar esse comando cria todas as tabelas definidas pelos arquivos de migrations em
database/migrations/
Se observar o database além das tabelas definidas nesse diretório de migrations, criou uma tabela adicional
chamada "migrations", essa tabela serve justamente para controlar qual(is) arquivos de migrations já foram
rodados e criou-se as tabelas a partir deles. Essa tabela é muito importante porque caso rode novamente o
comando anterior não tentará criar novamente a mesma tabela, justamente porque na tabela "migrations"
tem o histórico do que já rodou, e em qual sequência foi criado.
Em produção em alguns casos será necessário forçar o comando, para criar as tabelas a partir dos arquivos
de migrations, e para conseguir tal feito precisa combinar a opção --force:
php artisan migrate --force 
 
 
Reverter Migrations 
af://n221
af://n231
Se observar na tabela de migrations notará que ela possui uma coluna chamada "batch", essa é uma coluna
com valor inteiro, e ela armazena exatamente a sequência que a migration foi criada, ou seja, se criar um
tabela agora e rodar o comando o valor será 1, se criar um novo arquivo de migration e rodar novamente o
valor dos próximos arquivos de migrations serão 2, e assim sucessivamente.
O próximo comando está ligado justamente com esse valor. Para conseguir testar deixe primeiramente
apenas os arquivos de migrations default (users e password_resets) e rode o comando:
php artisan migrate 
 
Isso vai criar essas duas tabelas, e na tabela migrations o valor de batch estará como 1 para ambas. Agora
crie o arquivo de migration para a tabela de products, e rode novamente o comando para criar a tabela. Após
fazer isso, pode observar que a tabela migrations o valor de batch para esse novo arquivo de migration está
com 2.
Para reverter (fazer o roll back) das últimas migrations criadas podemos rodar o comando:
php artisan migrate:rollback 
Isso vai desfazer as últimas tabelas criadas.
Em alguns casos será necessário voltar não apenas 1 passo, ou seja, desfazer apenas as últimas migrations,
mas também desfazer algumas sequências anteriores, para isso podemos combinar a opção --step e
especificar quantos passos queremos voltar:
php artisan migrate:rollback --step=3 
 
Outra alternativa é fazer o roll back em todas as nossas migrations, para isso podemos usar o comando:
php artisan migrate:reset 
Após rodar esse comando não existirá nenhuma tabelaem seu banco de dados, exceto a tabela migrations e
sem conteúdo.
Quando rodamos esses comandos de roll back o método down dos nossos arquivos de migrations entram
em cena, e no caso, deleta a tabela.
 
 
Rollback e Migration 
Agora vamos imagina que a nossa tabela products precisa de uma nova coluna, chamada por exemplo
"featured" para indicar se o produto é destaque ou não, podemos adicionar essa nova coluna na tabela
através do método up na classe de migration:
af://n250
[...] 
public function up() 
{ 
 Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->string('name'); 
 $table->text('description'); 
 $table->boolean('featured')->default(false); 
 $table->timestamps(); 
 }); 
} 
[...] 
 
Se observar o banco de dados a estrutura do arquivo de migration não está coerente com a tabela,
precisamos resolver isso. Uma das alternativas é fazer o roll back (porque precisamos deletar essa tabela) e
recriar novamente com a nova estrutura, uma das alternativas é rodar estes dois comando, o primeiro deleta
as tabelas e próximo recria:
php artisan migrate:reset 
php artisan migrate 
Ou podemos rodar simplesmente o comando que deleta as tabelas (execulta o método down das classes de
migrations) e recria novamente (executa o método up das classes de migrations):
php artisan migrate:refresh 
Assim como o comando migrate:rollback, no comando migrate:refresh também podemos especificar quantos
passos queremos aplicar o comando, usando a opção --step:
php artisan migrate:refresh --step=3 
 
Deletar e Criar Novamente 
O comando migrate:fresh vai deletar todas as tabelas do database e recriar novamente (esse comando não
passa pelo método down dos classes de migrations, ele simplesmente deleta todas as tabelas e recria
novamente):
php artisan migrate:fresh 
 
 
 
af://n262
af://n268
Tabelas 
Criando Novas Tabelas 
Para criar novas tabelas usa o método estático create da facade Schema. O método create recebe dois
argumentos, o primeiro é o nome da tabela, enquanto o segundo é uma Closure (função de callback) com um
objeto de Blueprint, exemplo:
Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->timestamps(); 
}); 
 
É possível verificar se a tabela já existe, antes de criar, exemplo:
public function up() 
{ 
 // Só caso ainda não exista a tabela 
 if (!Schema::hasTable('products')) { 
 Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->string('name'); 
 $table->text('description'); 
 $table->timestamps(); 
 }); 
 } 
} 
 
Também é possível usar o método hasColumn para verificar se uma coluna já existe na tabela, exemplo:
if (Schema::hasColumn('products', 'name')) { 
 // 
} 
 
Outra alternativa possível da facade Schema é não usar a conexão default ao banco de dados, e sim usar o
método connection para indicar outra conexão que deseja aplicar ao usar essa migration:
Schema::connection('nome_conexao')->create('users', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->timestamps(); 
}); 
 
No momento de criar uma nova tabela é possível definir algumas opções para a tabela, exemplo:
af://n268
af://n269
Recurso Descrição
$table->engine = 'InnoDB';
Especifica a engine de armazenamento (Para bancos de dados
MySQL)
$table->charset = 'utf8mb4';
Especifica as configurações de caracteres padrão (Para bancos de
dados MySQL)
$table->collation =
'utf8mb4_unicode_ci';
Especifica a collation padrão para a tabela (Para bancos de dados
MySQL)
$table->temporary(); Cria uma tabela temporária (Exceto para SQL Server)
Um cuidado muito importante deve ser levado em conta no momento de renomear uma tabela, se
ela tiver chaves estrangeiras (foreign key) ao renomear pode perder a referencia da chave
estrangeira, e isso causa um grande problema.
 
 
Renomear e Deletar Tabelas 
O método down da classe de migration pode ser usado para deletar uma tabela, ou em alguns casos até
mesmo renomear. Para renomear uma tabela podemos usar o método rename da facade Schema:
Schema::rename($oldName, $newName); 
Schema::rename('products', 'produtos'); 
 
Outra alternativa é deletar uma tabela, no caso podemos usar o método drop:
Schema::drop('products'); 
 
Outra alternativa para deletar, porém mais segura é usando método dropIfExists, porque esse método antes
de efetivamente deletar a tabela checa se realmente ela existe:
Schema::dropIfExists('products'); 
 
 
 
Colunas 
af://n301
af://n314
O schema builder do Laravel contém uma grande variedade de opções de colunas para construir suas
tabelas.
Recurso Funcionalidade
$table->bigIncrements('id');
Auto-incrementing UNSIGNED BIGINT (primary key) equivalent
column.
$table->bigInteger('votes'); Coluna BIGINT.
$table->binary('data'); Coluna BLOB.
$table->boolean('confirmed'); Coluna BOOLEAN.
$table->char('name', 100); Coluna CHAR com tamanho opcional.
$table->date('created_at'); Coluna DATE (data).
$table->dateTime('created_at'); Coluna DATETIME (data e hora).
$table->dateTimeTz('created_at'); Coluna DATETIME (com fuso horário).
$table->decimal('amount', 8, 2);
Coluna DECIMAL com precisão (total de digitos) e escala (dígitos
decimais).
$table->double('amount', 8, 2);
Coluna DOUBLE com precisão (total de digitos) e escala (dígitos
decimais).
$table->enum('level', ['easy', 'hard']); Coluna ENUM.
$table->float('amount', 8, 2);
Coluna FLOAT com precisão (total de digitos) e escala (dígitos
decimais).
$table->geometry('positions'); Coluna GEOMETRY.
$table->geometryCollection('positions'); Coluna GEOMETRYCOLLECTION.
$table->increments('id'); Coluna auto incremental UNSIGNED INTEGER (chave primária).
$table->integer('votes'); Coluna INTEGER.
$table->ipAddress('visitor'); Coluna para endereço de IP.
$table->json('options'); Coluna para armazenamento JSON.
$table->jsonb('options'); Coluna JSONB.
$table->lineString('positions'); Coluna LINESTRING.
$table->longText('description'); Coluna LONGTEXT.
$table->macAddress('device'); Coluna endereço de IP MAC.
$table->mediumIncrements('id'); Coluna auto incremental UNSIGNED MEDIUMINT (chave primária).
$table->mediumInteger('votes'); Coluna MEDIUMINT.
$table->mediumText('description'); Coluna MEDIUMTEXT.
$table->morphs('taggable');
Adiciona a coluna taggable_id UNSIGNED BIGINT e
taggable_type VARCHAR, para relacionamentos polimórficos.
$table->multiLineString('positions'); Coluna MULTILINESTRING.
$table->multiPoint('positions'); Coluna MULTIPOINT.
$table->multiPolygon('positions'); Coluna MULTIPOLYGON.
Recurso Funcionalidade
$table->nullableMorphs('taggable'); Adiciona as colunas como nullable (null) para morphs() .
$table->nullableTimestamps(); Alias para o método timestamps() .
$table->point('position'); Coluna POINT.
$table->polygon('positions'); Coluna POLYGON.
$table->rememberToken();
Adiciona a coluna remember_token VARCHAR(100), com valor
padrão NULL.
$table->smallIncrements('id');
Auto-incrementing UNSIGNED SMALLINT (primary key) equivalent
column.
$table->smallInteger('votes'); Coluna SMALLINT.
$table->softDeletes();
Adiciona a coluna deleted_at TIMESTAMPS, com valor padrão
NULL, para o recurso de soft deletes.
$table->softDeletesTz();
Adiciona a coluna deleted_at TIMESTAMPS (com fuso horário),
com valor padrão NULL, para o recurso de soft deletes.
$table->string('name', 100); Coluna VARCHAR com tamanho opcional.
$table->text('description'); Coluna TEXT.
$table->time('sunrise'); Coluna TIME (horário).
$table->timeTz('sunrise'); Coluna TIME (com fuso horário).
$table->timestamp('added_on'); Coluna TIMESTAMP.
$table->timestampTz('added_on'); Coluna TIMESTAMP (com fuso horário).
$table->timestamps();
Adiciona as colunas created_at e a coluna updated_at
TIMESTAMPS, com valor padrão de NULL.
$table->timestampsTz();
Adiciona as colunas created_at e a coluna updated_at
TIMESTAMPS(com fuso horário), com valor padrão de NULL.
$table->tinyIncrements('id'); Coluna auto incremental UNSIGNED TINYINT (chave primária).
$table->tinyInteger('votes'); Coluna TINYINT.
$table->unsignedBigInteger('votes'); Coluna UNSIGNED BIGINT.
$table->unsignedDecimal('amount', 8, 2);
Coluna UNSIGNED DECIMAL com precisão (total de digitos) e escala
(dígitos decimais).
$table->unsignedInteger('votes'); Coluna UNSIGNED INTEGER.
$table->unsignedMediumInteger('votes'); Coluna UNSIGNED MEDIUMINT.
$table->unsignedSmallInteger('votes'); Coluna UNSIGNED SMALLINT.
$table->unsignedTinyInteger('votes'); Coluna UNSIGNED TINYINT.
$table->uuid('id'); Coluna UUID.
$table->year('birth_year'); Coluna YEAR (ano).
 
 
Modificar Colunas 
É possível também alterar colunas das tabelas através dos arquivos de migrations, ou seja, toda ou parte da
estrutura de uma tabela pode ser modificada, caso haja necessidade.
Para alterar a tabela de products por exemplo, podemos criar um novo arquivo de migration e definir qual ou
quais colunas queremos alterar, rode este comando para criar um novo arquivo de migration para alterar a
estrutura da tabela products:
php artisan make:migration create_products_table --table=produtos 
No método up do novo arquivo de migration vamos especificar que a coluna "description" não é obrigatório o
preenchimento, portanto, vamos definir essa coluna como valor null:
Schema::table('products', function (Blueprint $table) { 
 $table->string('description')->nullable(); 
}); 
 
Segue uma lista com todos as possibilidades para modificar colunas de tabelas, inclusive com modificadores
de índice:
af://n490
Modificador Descrição
->after('column') Ordena a coluna após outra coluna especifica (MySQL)
->autoIncrement()
Define coluna INTEGER com incremento automático (chave
primária)
->charset('utf8') Especifica o conjunto de caracteres para a coluna (MySQL)
->collation('utf8_unicode_ci') Especifica a collation da coluna (MySQL/SQL Server)
->comment('my comment') Adiciona um comentário a coluna (MySQL)
->default($value) Especifica um valor padrão para a coluna
->first() Define como a primeira coluna da tabela (MySQL)
->nullable($value = true)
Permite que valores NULL sejam inseridos na coluna, e o valor
padrão é NULL
->storedAs($expression) Cria uma coluna de armazenamento (MySQL)
->unsigned() Define a coluna INTEGER como UNSIGNED (MySQL)
->useCurrent()
Define que a coluna TIMESTAMP use CURRENT_TIMESTAMP
(timestamps atual) como valor padrão
->virtualAs($expression) Cria uma coluna virtual (MySQL)
->generatedAs($expression)
Cria uma coluna de identidade com opções de sequência
especificadas (PostgreSQL)
->always()
Define a precedência de valores de sequência sobre entrada
para uma coluna de identidade (PostgreSQL)
 
 
 
Índices 
Criando índices 
O schema builder possui suporte para vários tipos de índices. Uma das possibilidades é definir que os
valores da coluna são únicos, para isso podemos encadear o método unique na definição da coluna:
$table->string('title')->unique(); 
 
Outra alternativa é definir a coluna como índice após definir:
af://n547
af://n548
Método Descrição
$table->primary('id'); Define uma chave primária
$table->primary(['id', 'parent_id']); Define chaves compostas
$table->unique('email'); Define um índice único (valo único)
$table->index('state'); Define um índice simples
$table->spatialIndex('location'); Define um índice spatial. (Exceto para SQLite)
$table->string('title'); 
$table->unique('title'); 
 
O Laravel gera automaticamente um nome para o índice, porém, podemos passar um segundo argumento no
método unique e customizar o nome do índice:
$table->unique('title', 'unique_title'); 
 
 
Tipos de índices disponíveis 
Cada método de índice do schema builder aceita um segundo argumento opcional, que pode ser usado
justamente para definir um nome customizado para o índice. Quando não informa este segundo argumento
no método unique por padrão o usa-se o nomedatabela_nomedacoluna_recurso
 
 
Tamanho índices (MySQL / MariaDB) 
A partir da versão 5.4 o Laravel adotou o charset utf8mb4 como padrão, que possui suporte para armazenar
"emojis" no banco de dados. Porém, isso trouxe alguns "problemas", em bancos de dados MySQL <= 5.7.7 e
bancos de dados MariaDB <= 10.2.2 para colunas com índices precisa limitar o tamanho, o limite máximo
suportado por essas versões para campos com índices é 191. Para resolver isso, uma das soluções mais
práticas é definir a quantidade padrão de caracteres para as colunas, isso pode ser feito no Provider
AppServiceProvider ( app/Providers/AppServiceProvider.php ), no método boot inclua essa
configuração:
af://n559
af://n582
Método Descrição
$table->dropPrimary('users_id_primary'); Deleta a chave primária da tabela users.
$table->dropUnique('users_email_unique'); Deleta o índice único da tabela users.
$table->dropIndex('geo_state_index'); Deleta o índice da tabela "geo".
$table->dropSpatialIndex('geo_location_spatialindex');
Deleta o índice spatial da tabela "geo" (Exceto para
SQLite).
/** 
 * Bootstrap any application services. 
 * 
 * @return void 
 */ 
public function boot() 
{ 
 // Não esquece: use Illuminate\Support\Facades\Schema; 
 Schema::defaultStringLength(191); 
} 
 
 
Renomear índices 
Para renomear um índice pode usar o método renameIndex , este método aceita no primeiro argumento o
nome atual do índice, e o segundo argumento é novo nome para o índice:
$table->renameIndex('old_name', 'new_name') 
 
 
Deletar índices 
Para deletar um índice precisa usar o método correspondente ao índice criado, e indicar o seu nome. Por
padrão, o Laravel automaticamente identifica o índice pelo padrão nomedatabela_nomedacoluna_recurso,
veja algumas opções:
Ou, podemos simplesmente passar um array com o nome convencional do índice (prefiro desta forma, mais
simples):
Schema::table('users', function (Blueprint $table) { 
 $table->dropPrimary(['user_id']); // Deleta o índice de chave primária 
'users_id_primary' 
 $table->dropUnique(['email']); // Deleta o índice único 'users_email_unique' 
}); 
 
af://n587
af://n592
 
 
Chave estrangeira (Foreign Key) 
Felizmente o Laravel também possibilita criar chaves estrangeiras.
Resumidamente, chaves estrangeiras (foreign key) são usadas para restringir e forçar a integridade dos
registros relacionados em diferentes tabelas.
Vamos fazer algo bastante prático, vamos usar a nossa tabela products adicionar uma nova coluna chamada
user_id e vamos ligar o valor dessa coluna com a coluna id da tabela users . Essa coluna user_id seria
por exemplo id do usuário que é responsável pelo produto.
Podemos alterar a estrutura da nossa tabela products de duas formas, uma delas é criar um arquivo de
migration para fazer isso, com o comando:
php artisan make:migration add_user_id_to_users_table --table=products 
Porém, particularmente não gosto dessa opção, justamente porque teremos mais de um arquivo de
migration que trabalha com a mesma tabela, com o tempo isso pode deixar desorganizado a nossa aplicação.
A outra alternativa é adicionar a nova coluna na estrutura do arquivo de migrations atual
(create_products_table), e fazer o refresh da tabela. É exatamente essa opção que vamos seguir. Veja como
fica o método up:
public function up() 
{ 
 Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->unsignedInteger('user_id'); 
 $table->string('name'); 
 $table->text('description'); 
 $table->timestamps(); 
 
 $table->foreign('user_id')->references('id')->on('users'); 
 }); 
} 
Observe, primeiramente adicionamos a coluna user_id como UNSIGNET e INTEGER (inteira):
$table->unsignedInteger('user_id'); 
E após definimos a coluna user_id como chave estrangeira, referenciando a coluna id da tabela users:
$table->foreign('user_id')->references('id')->on('users'); 
af://n615
Também é possível definir aação desejada, com o método onDelete, ou com o método onUpdate. No
exemplo vamos definir: "on delete cascade", essa configuração ajuda a manter a integridade dos registros, e
evita registros órfãos no banco de dados, porque se deletar um usuário por exemplo, vai deletar
automaticamente todos os produtos ligados a este usuário.
$table->foreign('user_id') 
 ->references('id')->on('users') 
 ->onDelete('cascade'); 
Após redefinir a estrutura da tabela products, podemos atualizar, para isso no terminal rode o comando:
php artisan migrate:refresh 
 
 
Deletar chave estrangeira (foreign key) 
Para deletar uma chave estrangeira podemos usar o método dropForeign . As chaves estrangeiras também
usam o mesmo padrão de nomes que os índices, por padrão concatena
nomedatabela_nomedacoluna_recurso. Veja o exemplo para deletar a chave estrangeira da tabela de
products:
$table->dropForeign('products_user_id_foreign'); 
Ou, podemos simplesmente passar um array com o nome convencional da chave estrangeira (prefiro desta
forma, mais simples):
$table->dropForeign(['user_id']); 
 
Também podemos habilitar ou desabilitar restrições de chaves estrangeiras em nossas migrations, usando os
seguintes métodos:
Schema::enableForeignKeyConstraints(); 
 
Schema::disableForeignKeyConstraints(); 
 
af://n634
Database: Seeding 
Introdução 
Outro recurso extremamente útil do Laravel é o de Seeder. Para exemplificar como esse recurso pode ser útil
irei citar um exemplo.
Imagine que desenvolvemos uma aplicação com Laravel e terminamos de fazer o deploy (hospedar) o app em
um servidor, e nesse nosso sistema tem uma área restrita, ou seja, apenas pessoas autenticadas podem
acessar.
O que fazer para acessar?
Simples, neste caso podemos utilizar o recurso de Seeder, com este recurso é possível definir algumas rotinas
pré-configuradas para manipular banco de dados. Neste caso, é possível criar uma Seeder com os dados de
um usuário padrão para ter acesso ao sistema.
As classes de Seeder do Laravel ficam em database/seeds/
 
 
 
Criando uma Seeder 
Para criar uma nova Seeder no Laravel é bem simples, é possível utilizar o próprio artisan para criar a classe,
neste caso vamos criar uma Seeder para criar um novo usuário em nosso sistema. Veja o comando:
php artisan make:seeder UsersTableSeeder 
Esse comando vai gerar a classe em database/seeds/UsersTableSeeder.php
 
Definindo um Usuário Padrão 
Agora que criamos nossa classe de Seeder podemos abrir e criar uma lógica para inserir um novo usuário, na
classe UsersTableSeeder, o método run() deve conter a lógica para criar o novo usuáro, veja como fica:
use Illuminate\Database\Seeder; 
use App\User; 
 
class UsersTableSeeder extends Seeder 
{ 
 /** 
 * Run the database seeds. 
 * 
 * @return void 
 */ 
af://n644
af://n645
af://n654
af://n659
 public function run() 
 { 
 User::create([ 
 'name' => 'Carlos Ferreira', 
 'email' => 'carlos@especializati.com.br', 
 'password' => bcrypt('MinhaSenhaAqui'), 
 ]); 
 } 
} 
Agora que criou a classe de Seeder para inserir um novo usuário, o próximo passo é registrar essa nova
Seeder, para isso abra a classe DatabaseSeeder ( database/seeds/DatabaseSeeder.php ) e registre a nova
classe:
public function run() 
{ 
 $this->call(UsersTableSeeder::class); 
} 
No método run() deve ficar a lógica onde registra todas as Seeders, lembrando que pode ter várias chamadas
de diversas Seeders (pode ter quantas seeders for necessário).
O método $this->call() pode ser invocado várias vezes para registrar várias Seeders, ou pode também
receber um array com a Seeders a serem executadas:
public function run() 
{ 
 $this->call([ 
 UsersTableSeeder::class, 
 // ProductsTableSeeder::class, 
 ]); 
} 
 
 
 
Rodar Seeders 
Uma vez que criou a classe de Seeder, e registrou o próximo passo é simplesmente rodar e criar o novo
registro, em nosso caso irá criar um novo usuário, para isso rode este comando:
php artisan db:seed 
Caso tenha várias classes de Seeder registradas em DatabaseSeeder é possível especificar qual exatamente
é para executar, para isso use a opção --class :
php artisan db:seed --class=UsersTableSeeder 
af://n670
Neste caso mesmo que tenha várias classes de Seeders registradas vai rodar apenas a UsersTableSeeder .
 
Também é possível criar as Seeders no momento que criar as tabelas através do recurso de migration, veja
como:
php artisan migrate:refresh --seed 
Este comando vai recriar as tabelas e automaticamente rodas as Seeders registradas.
 
 
 
Factories 
Em ambiente de desenvolvimento em muitos casos é interessante inserir um grande volume de registros nas
tabelas para realizar testes de forma mais real. Porém, usar o recurso de Seeder para inserir estes registros
embora seja funcional, não é nada prático.
Podemos neste caso usar o recurso de factories e automatizar a inserção dos registros nas tabelas. Neste
exemplo vamos inserir 50 produtos automaticamente, primeiramente precisamos criar a classe de Factory,
para isso rode o comando:
php artisan make:factory ProductFactory 
Os arquivos de factories ficam armazenados em database/factories .
Também é possivel já adiantar o nosso trabalho, já vinculando o Factory ao model correspondente, no caso
ao model de Product (este model está em app/Models/), para isso basta usar a opção --model :
php artisan make:factory ProductFactory --model=Models\\Product 
O novo arquivo foi gerado em database/factories/ProductFactory.php , com o seguinte conteúdo:
use Faker\Generator as Faker; 
 
$factory->define(App\Models\Product::class, function (Faker $faker) { 
 return [ 
 // 
 ]; 
}); 
O método define recebe dois argumentos, o primeiro é o model (com o namespace), e o segundo argumento
é uma função callback, que recebe como parâmetro um objeto de Faker , e é justamente essa classe que
contém todos os recursos que precisamos para automatizar o processo de definição de valores para o que
será inserido em nossa tabela, no caso, na tabela products (porque estamos utilizando o model Product).
af://n683
Vamos definir a estrutura de inserção de registros na tabela de products de acordo com as limitações dessa
tabela, veja como fica:
use App\Models\Product; 
use Faker\Generator as Faker; 
 
$factory->define(Product::class, function (Faker $faker) { 
 return [ 
 'user_id' => 1, 
 'name' => $faker->unique()->name, 
 'description' => $faker->paragraph, 
 'featured' => false, 
 ]; 
}); 
Neste último exemplo definimos que a tabela products a coluna name será gerado um valor aleatório, porém
único. Para a coluna description também um valor aleatório com uma quantidade de caraceters maior, e a
coluna featured receberá um valor padrão de false, para todos os registros.
Existem centenas de opções e combinações possíveis para inserir valores aleatórios no banco de dados
utilizando o recurso de factory. Caso queira saber mais opções, sugiro que dê uma olhada nas propriedades
possíveis e comentadas na classe que está em vendor/fzaninotto/faker/src/Faker/Generator.php (não
pode alterar nada em vendor/, porém é totalmente valida a curiosidade de observar a implementação dos
recursos).
Simplesmente ter a classe de Factory pronta não resolve nada, precisamos fazer a chamada dela e especificar
quantos registros queremos criar aleatóriamente, no caso, vamos inserir 50 produtos. Precisamos criar um
novo seeder chamado ProductsTableSeeder :
php artisan make:seeder ProductsTableSeeder 
O arquivo foi gerado em database/seeds/ProductsTableSeeder.php
Para fazer a utilização da Factory ProductFactory precisamos usar o helper factory no método up do
seeder:
use Illuminate\Database\Seeder; 
 
class ProductsTableSeeder extends Seeder 
{ 
 /** 
 * Run the database seeds. 
 * 
 * @return void 
 */ 
 public function run() 
 {factory(App\Models\Product::class, 50)->create(); 
 } 
} 
NOTA: Como estamos usando um model (Product) (assunto que será abordado mais adiante)
precisamos criar o model, para isso rode o comando:
NOTA: Antes de rodar o seeder para criar o factory com os produtos dinamicamente, como estamos
trabalhando com o Model (que será abordado mais detalhadamente mais adiante), precisa criar um
atributo chamado `$fillable` com um array com os nomes das colunas no model `Product`
(`app/Models/Product.php`):
Observe que precisamos passar dois argumentos na função (helper) factory. O primeiro é model
correspondente, este primeiro parâmetro é muito importante, pois a identificação de qual Factory será
chamado é justamente pelo model. O segundo parâmetro é a quantidade de registros é para inserir, no caso
50. O método create que foi encadeado, é para indicar a ação, no caso, inserir novos registros.
Se o objetivo for por exemplo criar dinâmicamente um único registro, pode fazer desta forma:
$user = factory(App\User::class)->make(); 
php artisan make:model Models\\Product 
 
protected $fillable = ['user_id', 'name', 'description', 'featured']; 
 
 
Por último só precisamos configurar o Seeder ProductsTableSeeder na classe DatabaseSeeder
( database/seeds/DatabaseSeeder.php ):
public function run() 
{ 
 $this->call([ 
 UsersTableSeeder::class, 
 ProductsTableSeeder::class, 
 ]); 
} 
Para finalizar, resta apenas testar. Rode o comando para rodar os Seeders configurados, e observe que na
tabela products irá inserir 50 registros com valores aleatórios, após rodar o comando:
php artisan db:seed --class=ProductsTableSeeder 
Passamos a opção --class para rodar apenas o seeder ProductsTableSeeder , porque já rodamos o seeder
UsersTableSeeder em outra oportunidade.
 
 
Relacionamento de tabelas 
A tabela products na última alteração (no módulo de migrations) adicionamos a coluna user_id que é
justamente para relacionar o usuário ao produto, sendo este usuário o responsável pelo produto. Portanto,
ao rodar o exemplo acima está faltando algo, pois a coluna user_id precisa ser preenchida com algum valor,
mais precisamente com algum valor de ID da tabela de users.
Com o recurso de factories também é possível inserir dados relacionados, no exemplo a seguir vamos inserir
cinco novos usuários, e já vincular 25 produtos a cada novo usuário, tudo usando factories. Importante
lembrar que já existe um Factory padrão para usuários ( database/factories/UserFactory.php ).
factory(App\User::class, 5) 
 ->create() 
 ->each(function ($user) { 
 $user->products()->saveMany( 
 factory(App\Models\Product::class, 25)->make(['user_id' => null]) 
 ); 
 }); 
Lembrando que no model User ( app/User.php ) precisa ter o método products, que relaciona o usuário com
os produtos (não se preocupe sobre relacionamentos de tabelas, mais adiante vamos detalhar bastante este
assunto):
public function products() 
{ 
 // Não esquece: use App\Models\Product; 
 return $this->hasMany(Product::class); 
} 
Após fazer a alteração rode novamente o comando para criar os novos usuários e vincular 25 produtos a cada
um:
php artisan db:seed 
 
Para evitar erros com valor únicos nas tabelas, você pode deletar as tabelas, recriar novamente e já rodar os
seeders, desta forma:
php artisan migrate:refresh --seed 
 
af://n720
 
Eloquent 
Introdução 
O Eloquent é o nome ORM do Laravel, que fornece um simples e ao mesmo tempo robusta ActiveRecord para
manipular banco de dados. Normalmente cada tabela do banco de dados tem seu próprio Model, que é
usado para interagir com a tabela, e a partir desse Model é possível consultar os registros, inserir novos
registros, deletar e até mesmo alterar os registros.
Para explorar o Eloquent ORM do Laravel precisamos primeiramente configurar o acesso ao banco de dados,
e o arquivo de configuração de database no Laravel é o config/database.php (assunto já abordado no livro).
 
 
Criar Models 
Primeiro passo para explorar o Eloquent do Laravel é definir os Models, as classes (Models) ficam localizadas
por default (padrão) no diretório app/ . Todos Models do Eloquent devem herdar da classe
Illuminate\Database\Eloquent\Model .
Para criar um novo model, podemos usar o comando do artisan make:model NOME_MODEL , nesse exemplo
vamos criar o Model Product:
php artisan make:model Product 
 
Se conferir em app/ criou um nova classe chamada Product, com este conteúdo:
namespace App; 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 // 
} 
Esse é o conteúdo básico de um Model, mas, o mais importante é notar que a classe Product estende da
classe Model, que é a classe que disponibiliza os recursos do Eloquent.
Particularmente não gosto de armazenar os Models em app/ , prefiro criar pelo menos uma estrutura
app/Models/ para ficar um pouco mais organizado. Felizmente o artisan permite criar as classes de Models
em qualquer diretório em app/ , e caso não exista, ele o cria. Portanto, vamos salvar nossas classes de
Models em app/Models/ . Primeiro passo, delete o arquivo app/Product.php , acesse o terminal e rode o
comando:
af://n734
af://n735
af://n740
php artisan make:model Models\\Product 
Ao rodar o comando make:model passando Models\\ ele vai criar o arquivo em app/Models/Product.php , e
também o namespace da classe Product já estará correspondente ao path (caminho) da classe:
namespace App\Models; 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 // 
} 
 
É possível criar o Model e já automatizar mais um passo, que no caso é criar o arquivo de migration
correspondente:
php artisan make:model Models\\Product --migration 
Ou:
php artisan make:model Models\\Product -m 
 
A passar a opção --migration ou -m já cria o Model Product em app/Models/Product.php e também cria o
arquivo de migration correspondente ao model. Um ponto interessante é que ao criar o arquivo de migration,
tanto o nome do arquivo de migration, quanto o nome da tabela ficam no plural do model, como o nosso
model se chamam Product, logo a tabela no arquivo de migration será products , e o arquivo terá um nome
mais ou menos assim database/migrations/timestamps_create_products_table , com essa estrutura
inicial:
public function up() 
{ 
 Schema::create('products', function (Blueprint $table) { 
 $table->increments('id'); 
 $table->timestamps(); 
 }); 
} 
 
 
 
Padrões 
af://n764
O sistema de Eloquent do Laravel procura "adivinhar" algumas características das tabelas do banco de dados,
e por conta disso tem diversos padrões. Porém, o Laravel não é um framework engessado, ele permite que
você altere esses padrões e defina a estrutura das tabelas como preferir, e é exatamente isso que vamos ver
a partir de agora.
 
Nomes de Tabelas 
O Eloquent entende que o nome da tabela que o model representa sempre seja o nome do próprio model no
plural. Por exemplo, se tiver um model chamado Product, logo vai entender que o nome da tabela é products.
Se o model chama Category, logo o nome da tabela será categories, e assim por diante.
Porém, você tem liberdade de customizar, ou seja, definir um outro nome para a tabela. Vamos imaginar que
a nossa tabela se chama "produtos", e não "products", como fazer para identificar o nome customizado da
tabela no model? Simples, basta criar um atributo $table que recebe o nome da tabela atualizado:
protected $table = 'produtos'; 
 
Veja o exemplo:
namespace App\Models; 
 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 /** 
 * The table associated with the model. 
 * 
 * @var string 
 */ 
 protected $table = 'produtos'; 
} 
 
Chave Primária 
Por default a chave primária da tabela é a coluna ID, porém, nada lhe impede de alterar isso. No arquivo de
migration que mantém a estrutura da tabela a chave primária édefinida da seguinte forma:
$table->increments('id'); 
 
Mas, se quiser deixar por exemplo:
$table->increments('id_produto'); 
af://n767
af://n776
Isso é permitido!
Porém, quando sai do padrão sugerido, e altera o nome da chave primária precisa especificar no model qual
é o nome da coluna, para isso basta criar um atributo chamado $primaryKey , informando o nome da coluna
que é a chave primária da tabela:
protected $primaryKey = 'id_produto'; 
 
Outro detalhe sobre a chave primária é que definimos ela como auto-incremento, ou seja, ele vai definir
automaticamente o próximo valor de forma incremental. Porém, caso você quiser desabilitar esse auto-
incremento e depois definir manualmente o próximo valor, basta criar um atributo chamado $incrementing
no model do tipo boolean, recebendo o valor false para não incrementar:
protected $incrementing = false; 
 
Por default a chave primária é do tipo integer, mas, caso queira definir a chave primária com algum outro tipo
de valor, basta criar um novo atributo no model chamado $keyType recebendo o tipo da coluna primária:
protected $keyType = 'string'; 
 
Timestamps 
Por padrão ao criar um arquivo de migration ele já cria o arquivo pré-configurado com:
$table->timestamps(); 
 
Essa opção vai criar duas colunas adicionais na tabela, sendo elas: created_at e updated_at A coluna
created_at salva o timestamps atual quando insere um novo registro (isso o Laravel faz automaticamente). A
coluna updated_at salva o timestamps atual quando altera um registro (isso o Laravel faz automaticamente).
Porém em alguns casos essas colunas podem ser irrelevantes, e caso você opite por não as definir, vai gerar
um erro, porque o Laravel tenta inserir esses valores automaticamente, tanto na coluna created_at e na
coluna updated_at. Para desabilitar essas duas colunas precisa criar no model um atributo chamado
$timestamps recebendo o valor de false:
af://n793
namespace App\Models; 
 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 /** 
 * Indicates if the model should be timestamped. 
 * 
 * @var bool 
 */ 
 public $timestamps = false; 
} 
 
Porém, em alguns casos você pode optar por simplesmente alterar o nome das colunas, alterando de
created_at para data_criacao e de updated_at para data_alteracao. Nesse caso precisa criar no model duas
constantes com os valores atualizados dos nomes das colunas:
const CREATED_AT = 'data_criacao'; 
const UPDATED_AT = 'data_alteracao'; 
 
Por padrão o formato do timestamps das colunas created_at e updated_at são: 'Y-m-d H:i:s', porém caso
queira salvar o timestamps em outro formato, basta criar um atributo chamado $dateFormat no model
recebendo o valor desejado:
namespace App\Models; 
 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 /** 
 * The storage format of the model's date columns. 
 * 
 * @var string 
 */ 
 protected $dateFormat = 'd/m/Y H:i:s'; 
} 
 
 
 
Models 
af://n810
Uma vez que criou os models, que estão associados cada um a uma tabela do sistema, já podemos manipular
os registros das tabelas a partir dos models. Para manipular o model Product vamos criar um controller, para
facilitar o testes. Para criar um novo controller rode esse comando do artisan:
php artisan make:controller ProductController 
Veja que foi criado um arquivo em app/Http/Controllers/ProductController.php , e nessa class
ProductController que vamos realizar os testes. Defina um novo método chamado por exemplo tests, porque
é nele que inicialmente vamos realizar os testes:
public function tests() 
{ 
 
} 
 
Também precisa definir uma rota para acessar o método tests do controller ProductController, portanto, no
arquivo de rotas routes/web.php defina uma nova rota chamada por exemplo tests:
Route::get('tests', 'ProductController@test'); 
 
No Browser inicie a aplicação na rota tests: http://localhost/tests
 
 
Listando os registros 
Para listar os registros da tabela products , podemos fazer dessa forma:
public function tests() 
{ 
 // Não esquece de importar o Model Product: use App\Models\Product; 
 $products = Product::all(); 
} 
 
Para debugar o resultado, use o helper (método) dd:
public function tests() 
{ 
 $products = Product::all(); 
 dd($products); 
} 
http://localhost/tests
af://n822
 
Porém, como estamos apenas testando vamos listar os registros diretamente no controller (isso não é
recomendado, faça apenas para testes, o ideal é passar os dados para a view e ela lista)
public function tests() 
{ 
 $products = Product::all(); 
 
 foreach ($products as $product) { 
 echo "{$product->title} <br>"; 
 } 
} 
 
Nos exemplos utilizamos o método all para retornar todos os registros, também podemos usar o método get
para retornar todos os registros da tabela, o resultado será o mesmo.
 
 
 
Filtros 
Também é possível aplicar filtros para retornar os registro, nesse exemplo vamos retornar apenas os
produtos que estão ativos, para isso podemos combinar o método where:
public function tests() 
{ 
 $products = Product::where('active', true)->get(); 
 
 foreach ($products as $product) { 
 echo "{$product->title} <br>"; 
 } 
} 
 
O método where pode receber até 3 parâmetros: where('coluna', 'condição', 'valor'). Quando informa apenas
2 parâmetros o primeiro é a coluna e o segundo é o valor: where('coluna', 'valor'), nesse caso só o operador
assumido é o "="
Como listar apenas os registros inativos? Agora precisamos explorar o método where e passar 3 parâmetros,
porque a condição que precisamos usar para filtrar não é mais o "=" e sim o "!=" ou "<>" (diferente).
af://n836
public function tests() 
{ 
 $products = Product::where('active', '<>', true)->get(); 
 // ou: Product::where('active', false)->get(); 
 
 foreach ($products as $product) { 
 echo "{$product->title} <br>"; 
 } 
} 
 
Também é possível combinar várias condições, como por exemplo, exibir apenas os produtos ativos, e os
produtos cujo os preços são maiores ou igual a 20:
public function tests() 
{ 
 $products = Product::where('active', true) 
 ->where('price', '>=', 20) 
 ->get(); 
 
 foreach ($products as $product) { 
 echo "{$product->title} <br>"; 
 } 
} 
 
Caso queira analisar a query sql final troque o método get, pelo método toSql e debuge com o método dd:
public function tests() 
{ 
 $products = Product::where('active', true) 
 ->where('price', '>=', 20) 
 ->toSql(); 
 dd($products); 
} 
 
Mais detalhes sobre o método where no capitulo Query Builder
 
Um detalhe importante é que, quando usamos o método get ou o método all retorna uma collection (array),
que são instâncias de Illuminate\Database\Eloquent\Collection
E quando usamos o método first retorna apenas um único registro, e o retorno é um objeto do model
correspondente, exemplo:
public function tests() 
{ 
 $products = Product::get(); 
 // $products é uma collection (array com 0 ou N registros) 
 
 $product = Product::first(); 
 // Retorna apenas o primeiro resultado encontrado, logo $product é um objeto do 
model Product 
} 
 
 
 
Inserir 
Uma das maneiras de inserir um novo registro no database é criar uma nova instância do model, setar os
atributos, e usar o método save para inserir:
namespace App\Http\Controllers; 
 
use App\Models\Product; 
use Illuminate\Http\Request; 
use App\Http\Controllers\Controller; 
 
class ProductController extends Controller 
{ 
 /** 
 * Create a new product instance. 
 * 
 * @param Request $request 
 * @return Response 
 */ 
 public function store(Request $request) 
 { 
 $product = new Product; 
 $product->name = 'Produto x'; 
 $product->description = 'Descrição do produto x'; 
 $product->save(); // Cria novo produto 
 
 // Objetodo novo produto: 
 dd($product); 
 } 
} 
Veja que neste exemplo inserimos manualmente todas as propriedades, que são correspondentes aos nomes
das colunas da tabela. Os valores para as colunas created_at e updated_at são inseridos automaticamente
pelo Laravel.
af://n858
Embora seja algo muito funcional essa abordagem, não é produtivo, isso porque precisamos informar
manualmente o valor para cada coluna da nossa tabela que desejamos inserir algum valor. E se essa tabela
conter 100 colunas (algum possível e comum)? Neste método de desenvolvimento é extremamente
improdutivo.
Para resolver esse cenário podemos usar o método create e passar um array como parâmetro com todos
os valores que desejamos inserir, veja o exemplo:
public function store(Request $request) 
{ 
 $product = Product::create([ 
 'name' => 'Produto x', 
 'description' => 'Descrição do produto x', 
 ]); 
 
 // Objeto do novo produto: 
 dd($product); 
} 
Observe que o método create pode tornar o nosso trabalho mais produtivo, justamente por receber um array
com os valores que é para ser inserido, note também a coerência das chaves do array, devem ser exatamente
iguais aos nomes das colunas da tabela.
A vantagem deste formato é que podemos explorar o objeto de Request para recuperar todos os parâmetros
da requisição http (que podem ser valores que vem de um formulário) e tornar esse exemplo ainda mais
simples:
$product = Product::create($request->all()); 
O método all de Request retorna todos os parâmetros da requisição http, ou seja, se essa requisição vier de
um formulário automaticamente recupera os valores de todos os campos.
 
Mass Assignment 
Quando passamos para o método create ou para o método update $request->all() corremos o risco do
usuário passar parâmetros inesperados através da requisição HTTP, e estes valores podem afetar
diretamente os valores da tabela. Pense por exemplo, que na tabela users exista uma coluna chamada por
exemplo is_admin , caso o usuário envie intencionalmente is_admin com o valor de true (1)
automaticamente ele se torna um admin, o que neste caso coloca em risco o sistema, porque esse usuário
passa a ter privilégios administrativos dentro da aplicação.
Porém, o Laravel por padrão possui mecanismos que protege contra essa vulnerabilidade mass-assignment,
ao passar um array com os valores que deseja inserir ou editar, automaticamente o Laravel gera um
exception (um erro), justamente alertando que precisa especificar qual ou quais valores podem ser inseridos
desta forma.
Para resolver este caso precisamos acessar o model correspondente e criar um atributo chamado $fillable ou
$guarded.
af://n870
O atributo $fillable é o mais comum, ele recebe um array com todos as colunas que podem receber valores
de forma dinâmica, no caso do último exemplo, no model User não incluímos neste array a coluna is_admin .
Esse atributo indica a lista branca.
O atributo $guarded faz o papel contrário, ele também recebe um array, porém, com as colunas que não
podem receber o valor diretamente. Esse atributo indica a lista negra.
Para exemplificar, no model Product ( app/Models/Product.php ) vamos criar o atributo $fillable
especificando quais colunas podem receber valores dinamicamente:
namespace App\Models; 
 
use Illuminate\Database\Eloquent\Model; 
 
class Product extends Model 
{ 
 /** 
 * The attributes that are mass assignable. 
 * 
 * @var array 
 */ 
 protected $fillable = ['name', 'description']; 
 
 // [...] 
} 
Neste exemplo limitamos que apenas as colunas name e description podem receber valores dinâmicos
através do método create ou update .
Se o objetivo é indicar quais colunas NÃO devem receber um valor quando passa um array nos métodos
create ou update , deve utilizar o atributo $guarded, neste exemplo vamos restringir que não inseria valor
algum na coluna is_admin :
/** 
 * The attributes that aren't mass assignable. 
 * 
 * @var array 
 */ 
protected $guarded = ['is_admin']; 
Mesmo que passe um array com o valor para is_admin não será enviado para o banco de dados, porque
restringimos isso através do atributo $guarded .
Outra alternativa é usar o método fill para popular um array com os atributos:
$product = new Product; 
$product->fill($request->all()); 
$product->save(); // Cria novo produto 
 
 
 
Editar 
O método save pode ser usado tanto para inserir um novo registro a partir de um objeto do model, e
também pode ser usado para editar um objeto do model. Primeiramente, para atualizar um model
recuperamos o registro, definimos todos os atributos que desejamos atualizar, e novamente usamos o
método save , porém dessa vez para atualizar.
Ao atualizar algum registro automaticamente a coluna de timestemps updated_at será atualizada. Exemplo:
$product = Product::where('id', '=', $id)->first(); // ou: Product::find(1); 
$product->name = 'Novo Nome Para o produto id:1'; 
$product->save(); 
Neste exemplo atualizamos apenas o valor para a coluna name , porém qualquer outra informação poderia
ser editada.
Outra alternativa para editar um registro de forma mais produtiva é usando o método update , assim como o
método create também podemos passar um array com todos os valores a serem atualizados. Mas lembre-
se, a coerência com as chaves do array com o nome das colunas da tabela.
$products = Product::where('id', '=', $id) 
 ->update([ 
 'name' => 'Novo Nome Para o 
produto id:1', 
 ]); 
Neste exemplo todos os produtos cujo a coluna id seja igual ao valor da variável $id serão atualizados a
coluna name para o valor indicado.
Outra abordagem com o mesmo seria:
$product = Product::where('id', '=', $id)->first(); // ou: Product::find(1); 
 
$product->update([ 
 'name' => 'Novo Nome Para o produto id:1', 
]); 
 
Um exemplo mais real, suponha que a tabela products possua uma coluna chamada active (booleana),
que indica se o produto está ativo, ou não. Neste exemplo, vamos ativar todos os produtos que estão
desativados:
$products = Product::where('active', false) 
 ->update([ 
 'active' => true, 
 ]); 
af://n887
 
 
 
Deletar 
Claro, além de buscar os registros, inserir novos, editar, não pode faltar a opção de deletar, veja como:
// Recupera o produto pelo ID 
$product = Product::where('id', $id)->first(); // Ou simplesmente: Product::find($id); 
 
// Deleta o produto 
$product->delete(); 
 
 
Filtrar e excluir 
Também é possível deletar em massa, aplicando um filtro ( where ), neste exemplo vamos deletar todos os
produtos inativos:
// Deletando todos os produtos inativos 
Product::where('active', false)->delete(); 
 
 
Excluir pela chave primária 
Outra alternativa até mais simples para deletar um ou mais registros é usando o método destroy , esse
método recebe como argumento o valor da chave que é para remover o registro ( id ).
// Deletando o produto id=1 
Product::destroy(1); 
// Deletando os produtos id=1,2,3 
Product::destroy(1, 2, 3); 
// Deletando os produtos id=1,2,3 
Product::destroy([1, 2, 3]); 
// Deletando todos os produtos inativos 
$products = Product::where('active', false)->get(); 
Product::destroy($products); 
af://n903
af://n908
af://n913
 
 
 
Soft Deleting 
Outro recurso interessante do Laravel e que se mostra muito útil em diversos cenários é o Soft Deleting, este
recurso permite "deletar" o registro sem excluir.
Como assim?
É possível criar um tabela com uma coluna "deleted_at", essa coluna é do tipo date (data).
O Eloquent do Laravel por padrão seleciona apenas os registros que possuem a coluna "deleted_at" não
preenchidos preenchidos, ou seja, com o valor de null.
Quando está utilizando o recurso de Soft Deleting ao deletar o registro, o mesmo não é apagado da tabela,
apenas o campo deleted_at é preenchido com as informações de timestamps. E quando consulta o registro,
por padrão só retorna os registros com a coluna deleted_at está igual anull, ou seja, registros que não foram
"deletados".
Isso é interessante quando se tem informações valiosas no banco de dados, porque não é interessante neste
caso que estes registros sejam apagados, como por exemplo, registros de usuários. Não é interessante excluir
definitivamente um registro de usuário no sistema.
Para criar a coluna deleted_at na tabela, no arquivo de migration da tabela correspondente basta adicionar:
$table->softDeletes(); 
Essa opção cria a coluna deleted_at na tabela.
 
 
Utilizando o Recurso de Soft Deleting 
Para utilizar é muito simples, basta utilizar a Trait SoftDeletes no Model correspondente, apenas isso. Veja um
exemplo prático:
namespace App\Models; 
 
use Illuminate\Database\Eloquent\Model; 
use Illuminate\Database\Eloquent\SoftDeletes; 
 
class Product extends Model 
{ 
 use SoftDeletes; 
 
 /** 
 * Opcional, informar a coluna deleted_at como um Mutator de data 
 * 
af://n922
af://n934
 * @var array 
 */ 
 protected $dates = ['deleted_at']; 
} 
Agora ao selecionar os registros utilizando o model Product irá retornar apenas os registros que não foram
apagados, ou seja, os registros cujo o valor da coluna deleted_at é igual null:
#controller 
public function index(Product $product) 
{ 
 $products = $product->get(); 
 
 dd($products); 
} 
 
Para analisar a query final e observar o filtro na coluna deleted_at , utilize o método toSql :
$products = $product->toSql(); 
dd($products); 
// Resultado: select * from products where deleted_at=null 
 
 
Incluindo Registros Deletados 
Uma alternativa possível é recuperar todos os registros, incluindo os que foram deletados com Soft
Deleted , para isso usamos o método withTrashed :
// Ex1: 
$products = Product::withTrashed()->get(); 
// Query: select * from products; 
 
// Ex2: 
$products = Product::where('active', true)->withTrashed()->get(); 
 
No capitulo sobre relacionamentos de tabelas será abordado isso com mais detalhes, porém, é importante
saber que é possível aplicar este mesmo filtro para retornar os registros relacionados que foram deletados
também:
$product = Product::find(1); 
$comments = $product->comments()->withTrashed()->get(); 
 
af://n944
 
Recuperando Apenas os Deletados 
Também é possível trabalhar apenas com os registros que foram deletados com Soft Deleted , para isso
usamos o método onlyTrashed :
// Ex1: 
$products = Product::onlyTrashed()->get(); 
// Query: select * from products where deleted_at<>null; 
 
// Ex2: 
$products = Product::where('active', true)->onlyTrashed()->get(); 
 
Também é possível retornar apenas os registros relacionados que foram deletados:
$product = Product::where('id', 1)->first(); 
$comments = $product->comments()->onlyTrashed()->get(); 
 
 
Restaurando 
Como obviamente o registro não foi efetivamente deletado, podemos restaurar quando necessário, neste
exemplo vamos restaurar os produtos, para isso usamos o método restore :
// Ex1 (restaurando todos): 
Product::withTrashed()->restore(); 
 
// Ex2 (restaurando apenas os ativos): 
Product::where('active', true)->withTrashed()->restore(); 
 
Também é possível restaurar os registros relacionados, no exemplo vamos restaurar todos os comentários do
produto 1:
$product = Product::where('id', 1)->first(); 
$product->comments()->restore(); 
 
 
Deletar Permanentemente 
af://n952
af://n960
af://n968
Em alguns casos pode ser necessário deletar um registro permanentemente, para isso podemos usar o
método forceDelete :
$product = Product::where('id', 1)->first(); 
$product->forceDelete(); 
// Tudo na mesma linha: Product::where('id', 1)->first()->forceDelete(); 
 
Também podemos deletar permanentemente todos os registros relacionados, neste exemplo vamos deletar
todos os comentários do produto 1:
$product = Product::where('id', 1)->first(); 
$product->comments()->forceDelete(); 
 
 
 
Outras Opções 
firstOrCreate 
O método firstOrCreate recupera o registro caso exista, ou, cria um novo registro. Vamos ao exemplo:
$product = Product::firstOrCreate([ 
 'name' => 'Produto Nome', 
 'description' => 'Descrição do Produto', 
]); 
dd($product); 
Neste exemplo, primeiramente verifica se existe algum produto cujo o valor da coluna name seja igual a
"Produto Nome" e o valor para a coluna description seja igual a "Descrição do Produto", se encontrar o
registro com estes valores devolve o objeto do model de Product para a variável $product, caso contrário, cria
um novo produto com estes valores e devolve o objeto de Product.
A vantagem dessa abordagem é que garante que não haja registros com valores idênticos duplicados no
banco de dados. Faça o teste, tente inserir diversas vezes o mesmo registro com essa implementação
(atualize a página diversas vezes), no final, terá apenas um único registro.
 
 
firstOrNew 
af://n977
af://n978
af://n985
O método firstOrNew trabalha muito semelhante ao firstOrCreate , porque não insere um registro
duplicado, porque verifica se o registro já existe na tabela. Porém, precisa especificar que é para inserir, isso
porque quando não encontra o registro ele não insere imediatamente, na realidade o método firstOrNew
retorna um novo objeto do model, e para inserir precisa chamar o método save , veja o exemplo:
// Verifica se existe um produto com esse nome e descrição: 
$product = Product::firstOrNew([ 
 'name' => 'Produto Nome', 
 'description' => 'Descrição do Produto', 
]); 
// Se existir retorna o objeto com os dados do produto, caso contrário retorna uma nova 
instância de Product. 
 
// Insere o registro, caso não exista ainda 
$product->save(); 
 
dd($product); 
 
 
updateOrCreate 
O método updateOrCreate é muito útil e interessante, porque ele pode inserir ou simplesmente atualizar
um registro. Esse método recebe dois parâmetros, o primeiro são as condições, e o segundo, o que é para
atualizar. Exemplo:
$product = Product::updateOrCreate( 
 [ 
 'name' => 'Produto Nome', 
 'description' => 'Descrição do Produto', 
 ], 
 ['description' => 'Nova descrição'] 
); 
dd($product); 
Neste exemplo, primeiramente verifica se existe algum produto cujo o valor da coluna name seja igual a
"Produto Nome" e o valor para a coluna description seja igual a "Descrição do Produto", se encontrar o
registro atualiza o valor da coluna description para "Nova descrição" (porque é o segundo parâmetro do
método que define o que será atualizado).
 
 
Comparando Models 
Em alguns casos pode que eventualmente seja necessário comparar se os models são iguais. O método is
pode ser usado para comparar, veja:
af://n990
af://n996
$user = User::find(1); 
if ($product->is($user)) { 
 // 
} 
 
Eloquent Relacionamentos de Tabelas 
Bancos de dados relacionais permitem relacionar registros em diferentes tabelas. Os relacionamentos
possíveis são:
One to One (Um para Um)
One to Many (Um para Muitos)
Many to One (Muitos para Um)
Many to Many (Muitos para Muitos)
 
O Eloquent do Laravel permite trabalhar com todos os relacionamentos citados acima, de forma muito fácil e
simples, e ainda dispõe de mais algumas artimanhas para ajudar a relacionar registros seguindo outras
opções:
Has Many Through
Polymorphic Relations (Relações Polimórficas)
Many To Many Polymorphic Relations (Muitos para Muitos - Relações Polimórficas)
af://n1002
https://www.youtube.com/watch?v=Ofi18M5kLgY
https://www.youtube.com/watch?v=1P7aPUh5WLQ
https://laravel.com/docs/5.7/eloquent-relationships#polymorphic-relationships
Eloquent Relationships One to One 
Esse é o relacionamento mais básico. Pense em um sistema onde o usuário pode ter informações por
exemplo de latitude e longitude. Essas suas informações podem até estar na tabela de users junto com as
demais colunas, porém fica mais didático ter uma outra tabela simplesmente para quebrar essas
informações e tornar a tabela de users mais simples possível.
Nesse exemplo vamos criar uma tabela chamada locations, para amazenar

Outros materiais