Tutorial Laravel para iniciantes - Parte 06 [Relacionando models com o Eloquent ORM, criando migrations e seeds]


Nesse post iremos criar um select no formulário de cadastro iremos aprender como fazer inter relações entre tabelas ligadas por chaves estrangeiras e também iremos aprender como trabalhar de forma incrivelmente pratica utilizando o Eloquent!

Glossário:


1) Criando a tabela Categoria

Para agilizar o processo vamos fazer uso do comando artisan, abra o terminal no diretório do projeto Laravel e rode o seguinte comando:
php artisan make:model Categoria -m
Com isso criamos a classe Categoria que estende a classe model dentro do diretório app/ o parâmetro "-m" também já cria Schema da nossa tabela Categoria que fica localizado no diretório database/migratórios, no meu caso com o seguinte nome: "2017_04_25_120022_create_categorias_table.php".
php artisan make:model Categoria -m

Agora vamos editar esse nosso arquivo, abra o Schema criado e adicione ao método up:
public function up()
    {
        Schema::create('categorias', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nome');
            $table->string('descricao');
            $table->timestamps();
        });
    }
Salve o arquivo e agora vamos executar o artisan para criar a tabela no banco de dados:
php artisan migrate
php artisan migrate

2) Adicionando categorias de teste

Precisamos adicionar informações em nossa tabela Categoria e para isso precisamos criar um seed para incluir esses registros.
Laravel inclui um método simples de preencher seu banco de dados com dados de teste usando classes de semente. Todas as classes de semente são armazenadas no diretório database/seeds. Classes seed podem ter qualquer nome que desejar, mas provavelmente deve seguir algumas convenções sensatas, como UsersTableSeeder, etc. Por padrão, uma classe DatabaseSeeder é definida para você. A partir desta classe, você pode usar o método de chamada para executar outras classes de seed, permitindo que você controle a ordem de propagação.
Para criarmos um seed novamente iremos utilizar o poderoso artisan:
php artisan make:seed CategoriaSeed
Esse comando cria a classe CategoriaSeed que estende a classe Seeder dentro do diretório database/seeds/
php artsan make:seed CategoriaSeed

Agora vamos adicionar as nossas categorias e para isso acesse o diretório database/seeds e edite o arquivo CategoraSeed.php:
use App\Categoria;
use Illuminate\Database\Seeder;

class CategoriaSeed extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Categoria::insert(['nome' => 'Dúvidas', 'descricao' => 'Tire suas dúvidas aqui!']);
  Categoria::insert(['nome' => 'Sugestões', 'descricao' => 'Gostaria de sugerir alguma alteração?']);
  Categoria::insert(['nome' => 'Outros', 'descricao' => 'Fale o que você quiser para mim!']);
    }
}
Volte ao terminal e execute o comando:
php artisan db:seed --class="CategoriaSeed"
Repare no comando, nesse caso definimos que a somente classe CategoriaSeed será adicionado ao nosso banco, caso não queria definir algum seed especifico basta não passar o parâmetro --class="".
Usando o comando php artsan db:seed, note que esse comando não retorna nenhuma informação!

Caso ocorra o erro dizendo que a classe não exista:
[ReflectionException]
Class CategoriaSeed does not exist
Basta executar o comando a baixo:
composer dump-autoload
Após isso tente rodar o comando seed;


Agora se quiser pode ir no eu banco de dados conferir que todos os dados estarão lá!
phpMyAdmin

3) Alterando a tabela de contatos

Aqui vamos adicionar id_categoria a tabela contatos, então volte ao terminal e execute o seguinte comando:
php artisan make:migration --table="contatos" alter_contatos_table
Comando e resultado do php artisan make:migration ....

Esse comando irá criar a classe AlterContatosTable estendido da classe Migration dentro do diretório database/migrations/ no arquivo 2017_04_25_161822_alter_contatos_table.php, vamos editar esse arquivo:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AlterContatosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('contatos', function (Blueprint $table) {
            $table->integer('id_categoria')->unsigned()->nullable();
            $table->foreign('id_categoria')->references('id')->on('categorias');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('contatos', function (Blueprint $table) {
            $table->dropForeign('contatos_id_categoria_foreign');
        $table->dropColumn('id_categoria');
        });
    }
}
Salve e vamos para o terminal execute o comando:
php artisan migrate
Ao executar o comando Migrate será criada a coluna id_categoria na tabela contato, isso acontece porque o Laravel encontrou uma nova migration e executou o comando up();
php artisan migrate

Após a execução podemos olhar no nosso banco as alterações do migrate:
phpMyAdmin id_categoria adicionado


Agora vamos supor que precise desfazer e para isso existe o comando rollback, então vamos usá-lo!
php artisan migrate:rollback
php artisan migrate:rollback

O comando migrate:rollback executa o comando donw(); dentro da nossas classes estendidas de Migration, agora se acessarmos o nosso banco percebemos que não está mais lá a id_categoria (que adicionamos anteriormente).
phpMyAdmin após o Rollback
Rode novamente o caso tenha executado o exemplo do rollback:
php artisan migrate
E vamos continuar com o próximo passo.

4) Adicionando relação entre o model Contato e Categoria

Em nosso exemplo a relação de cardinalidades entre as tabelas contato e categoria é de 1:N, ou seja, o contato pode ter uma categoria, e a categoria pode ter vários contatos.

Abra o app/Contato.php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Contato extends Model
{
 public function categoria(){
  return $this->belongsTo(Categoria::class, 'id_categoria');
 } 
}
Criamos o método categoria e ao fazer isso, podemos recuperar a categoria de um contado da seguinte forma:
$categoria = $contato->categoria;

Mesmo chamando como se fosse um atributo, o Eloquent encontra o método que definimos no model e retorna a instância da classe Categoria, caso exista e isso funciona graças aos Métodos Mágicos do PHP.
OBS.: Tive um grande problema, por padrão o Eloquent trabalha com as colunas da seguinte maneira "nome"+_id, no nosso exemplo deveria ser categoria_id, porem por padrão pessoal eu utilizo um modelo diferente, id_+"nome", isso é id_categoria, por consequência disso acabei empacando nos estudos.
Quando utilizado o padrão do Eloquent não é necessário definir o nome da coluna com a chave estrangeira, somente:
return $this->belongsTo(Categoria::class);
No meu caso foi necessário adicionar o seguinte parâmetro:
return $this->belongsTo(Categoria::class, 'id_categoria');
Com isso resolve o problema de não funcionar.

5) Adicionando um select ao formulário de contatos

Abra o view localizado em resources/views/welcome.blade.php e vamos adicionar o nosso select, utilizando do padrão MVC: Aqui deixei entre comentários aonde fiz a alteração nessa etapa.

6) Salvar id_categoria em contatos

Acesse o diretório app/Http/Controllers/ e abra o arquivo ContatoController.php:
namespace App\Http\Controllers;

use App\Http\Requests\ContatoEnviarRequest;
use Illuminate\Http\Request;
use App\Contato;

class ContatoController extends Controller
{
    
 /* Exibe o formulário para enviar uma mensagem */ 
 public function index(){ 
  return view('welcome');
 } 
 /** 
 * Insere a mensagem no banco de dados
 */
 public function enviar(ContatoEnviarRequest $request, Contato $contato, \App\NotificacaoInterface $notificar){
  $contato->nome = $request->get('nome');
  $contato->email = $request->get('email');
  $contato->mensagem = $request->get('mensagem');
  // Adicionado aqui:
  $contato->id_categoria = $request->get('id_categoria');
  // fim da adição!
  $contato->save();
  echo "Sua mensagem foi armazenada com sucesso! Código: " . $contato->id; 
  $notificar->notificar();
 } 

 /**
 * Exibe uma listar com as mensagens cadastradas 
 */ 
 public function listar(){
  return view('listar', array('contatos' => Contato::all()));
 }
}
Aqui basicamente só adicionamos ao método a seguinte variável:
$contato->id_categoria = $request->get('id_categoria');
Para salvarmos o nosso id_categoria na tabela contato;
Vamos testar, abra seu formulário e preencha os campos (todos eles, pois temos a validação do tutorial anterior) e salve confira no banco de dados que a nova coluna receberá o id passado.

7) Exibindo o nome da categoria na lista

Agora que já temos os dados em nossa tabela precisamos também exibir eles relacionados, pois na tabela contato não é salvo o nome relacional e sim o seu id (chave). Abra a view listar.blade.php que está localizada no diretório resources/views/ e vamos edita-la:
Repare que basicamente adicionamos a linha 20 (cabeçalho da tabela) e a linha 30, é nela que vamos nos atentar, o Eloquent faz o relacionamento bastando chama a categoria e definir o objeto, (nome ou descrição) e pronto! Certamente isso facilita muito a criação de grids que necessitam de parâmetros relacionais além de tornar extremamente mais rápida e pratica (isso quando funciona e claro), e com isso finalizo o nosso 6 tutorial. Já já teremos o próximo!

Caso tenha ficado alguma dúvida (que certamente vai fica, porque até eu tenho dúvida, comenta aqui em baixo que nós aprendemos juntos!



Se vocês gostaram desse Post não deixe de compartilhar com seus amigos!!!
E para não perder nenhuma novidade nos sigam nas redes sociais:
Twitter: @Bulfaitelo
Share on Google Plus

About Thiago Rodrigues

Formado em Sistema de Informação pela Faculdade Paraíso
O que falar de mim? Não á muito, mas garanto que meu objetivo aqui é somente ajudar!
Atualmente desenvolvendo o projeto do QiEstudo.

Comentários
0 Comentários

0 comentários:

Postar um comentário

Observação: somente um membro deste blog pode postar um comentário.