laravel5essencial

87

description

Livro de Laravel 5

Transcript of laravel5essencial

  • Laravel 5: EssencialAlta produtividade no mundo Real

    Wesley Willians Ramos da SilvaEsse livro est venda em http://leanpub.com/laravel5essencial

    Essa verso foi publicada em 2015-05-23

    This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishingprocess. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools andmany iterations to get reader feedback, pivot until you have the right book and build traction onceyou do.

    2015 Wesley Willians Ramos da Silva

  • Dedico esse meu primeiro livro minha princesa Sarah.

  • Contedo

    Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    Instalao via Laravel Installer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Instalao direta via composer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6Executando Laravel pela primeira vez . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    A estrutura do Laravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Estrutura de pastas e arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Ciclo de vida de uma aplicao Laravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    Configurando sua aplicao Laravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Alterando o Namespace de sua aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Configurando banco dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Configurando envio de emails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14Configurao do ambiente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14Concluindo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    Trabalhando com Rotas, Controllers e Views . . . . . . . . . . . . . . . . . . . . . . . . . 16Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16Voltando s Rotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Apontando para uma view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Falando sobre Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Configurando um banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22Criando nosso primeiro Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    Rumo ao primeiro CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Listando nossos Produtos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Criando novos produtos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Removendo registro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49Editando registro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

  • CONTEDO

    Ajustando rotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53Linkando listagem de produtos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

    Relacionando Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61Criando Model e Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61Criando relacionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62Tabela Pivot (ManyToMany) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

    Container de servios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72Servios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72Dependency Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73Containers de servios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

  • IntroduoSabemos que o mundo PHP est evoluindo exponencialmente, principalmente depois das diversasiniciativas de interoperabilidade como o PHP-FIG com suas PSRs e o surgimento do composer, quenos permite instalar quaisquer tipos de biblioteca de forma plug n play .Com o ecosistema todo aquecido, onde o compartilhamento de bibliotecas e frameworks tornou-sealgo extremamente simples, muitos projetos rapidamente comearam a ficar em evidncia, incluindoo Laravel Framework.Tenho que admitir que pela primeira vez que ouvi falar no Laravel, meu primeiro pensamento foi (eacredito que de muitos outros desenvolvedores tambm):

    Mais um framework PHP? Para que? Quais as vantagens que esse camarada pode trazer em cima de frameworks to bem feitoscomo: Zend Framework, Symfony, etc.?

    Admito que simplesmente ignorei o projeto.Quemme conhece, sabe que sou uma pessoa extremamente focada e raramente fico divagando entremuitos projetos. Apesar de gostar de experimentar muito, totalmente impossvel ficar testandomilhares de bibliotecas e frameworks o tempo todo.Conforme o tempo passou, percebi que a cada dia muitos desenvolvedores comearam a falar maise mais sobre o Lavarel, e nesse ponto resolvi instalar e dar uma brincada.Quando fiz a instalao da verso 3 em meu computador, simplesmente fiquei extremamentedesapontado. O Laravel me lembrava o Zend Framework 1, commuitas simplificaes, e algumasmprticas de desenvolvimento, que para o contexto em que estvamos vivendo eram inadimissveis.Logo depois, o Laravel comeou a utilizar muitos componentes do Symfony 2, um dos frameworksque mais admiro, e nesse ponto quando fui analisar novamente o framework me fiz a seguintepergunta: Por que vou utilizar o Laravel, se posso usar diretamente o Symfony?Por outro lado, e isso fato, a popularidade do Laravel cresceu ainda mais e esse ponto no pode serignorado. Quando algo se torna popular, pode ter certeza que o mercado de trabalho ser afetadoinstantaneamente.Finalmente em 2015 tivemos o release da verso 5 do Laravel, e com muitas novidades em relao averso 4. Tambm j podemos ver que claro que o framework sim est aplicando muitos conceitosinegavelmente bem bacanas, principalmente para quem gosta de mgica em um framework.Nesse ponto voc deve estar se perguntando: Como assim mgica?

  • Introduo 2

    Sabemos que os frameworks tem o grande objetivo de agilizar nossa vida, evitando reuso de cdigoe trazendo muitas funcionalidades prontas, por outro lado, existem frameworks que apesar detrazerem todos esses recursos e facilidades prontas, eles diretamente exigem que voc trabalhe comtodos esses componentes de forma explcita, ou seja, declarando tudo e como cada item vai serutilizado. Um exemplo muito claro desse tipo de framework o prprio Zend Framework 2. CadaController, Helper, Service, Factory, etc precisam estar claramente registrados, manualmente, nosarquivos de configurao.H desenvolvedores que no gostam desse tipo de abordagem, pois acham que o processo dedesenvolvimento fica altamente burocratizado. Por outro lado, h desenvolvedores que preferemclaramente isso, uma vez que eles tem certeza e controle de tudo que est acontecendo por trs doframework.Um exemplo que gosto demencionar em relao a isso : Voc pode ter um carro com cmbiomanuale automtico. Para muitos motoristas, usar cmbio manual algo altamente mais prazeroso, pois elespodem ter mais controle do carro; por outro lado, h motoristas que simplesmente no querem ter100% de controle, e no fazem a mnima questo de saber qual a prxima marcha que ele utilizar.Pois . Eu poderia claramente dizer que o Zend Framework 2 o carro com cmbio manual, j oSymfony, o com cmbio automtico. Agora voc deve estar se perguntando: e o Laravel?O Laravel carro da Google que dirige sozinho! Ele tomgico que realmente a nica comparaoque encontrei. Agora veja bem, no estou dizendo que isso bom ou ruim, estou dizendo que issodepende e muito do perfil do desenvolvedor.Para que eu no fique dando apenas exemplos abstratos, vamos tentar pegar um exemplo concretode um recurso do Laravel 5 chamado de: Method Injection.Imagine que dentro de uma classe de Controller, voc possui uma ao e essa ao necessita receberem uma dependncia de uma classe qualquer.Seguindo os exemplos que dei entre: ZF 2 e Laravel, temos as seguintes resolues para esseproblema.No Zend Framework 2:Dentro da classe do controller, teramos ummtodo chamado de setMyObject(MyNamespaceMyObject$object).

    1 // IndexController.php23

  • Introduo 3

    10 private $myObject;1112 public function indexAction()13 {14 $myObject = $this->myObject;15 }1617 public function setMyObject(\My\Namespace\MyObject $object)18 {19 $this->myObject = $object;20 }21 }2223 // IndexControllerFactory.php2425

  • Introduo 4

    que a injeo de nosso objeto nesse controller foi algo totalmente explcito, ou seja, 0% mgica.Simplesmente, determinamos como um controller vai ser criado e quais objetos temos que injetarno mesmo.J no Laravel (um outro extremo), simplesmente precisamos disso para termos o mesmo efeito:

    1 // IndexController.php2 public function indexAction(\My\Namespace\MyObject $object)3 {4 $myObject = $object;5 }

    Apenas isso! No momento que voc utiliza o Type Hint dizendo qual o tipo de objeto deve serrecebido nessa action, o prprio framework, magicamente, faz a injeo disso para voc.Entenda, isso no errado, mas voc precisa entender bem do framework para que voc no percao controle da sua aplicao.Independente dos aspectos tcnicos do Laravel, o mesmo ganhou explosivamente em popularidadede qualquer outro framework PHP do mercado (de acordo com a pesquisa do SitePoint ).Isso jamais deve ser ignorado.O Laravel sim, ainda possui suas inmeras polmicas implementaes de design, que ao seremanalisadas a fundo (como suas Faades, por exemplo), podem tirar do srio qualquer desenvolvedormais experiente que realmente goste de trabalhar com design e padro de projetos a risca. Alm disso,se por um lado ele implementa em sua verso 5 recursos como: Events, RouteMiddleware, Contracts,Commands, etc; por outro lado, muito claro que ainda ele no possui solues to elegantes paramodularizar grandes aplicaes como o Symfony e o Zend Framework o fazem com seus Bundles eModules, gerando uma grande limitao no prprio framework.O Laravel j uma realidade no mundo do PHP e provavelmente ele no ir parar na verso 5.Nesse livro, vou lhe apresentar de forma conceitual e prtica como trabalhar com Laravel, utilizandoseus principais recursos inseridos na verso 5, abusando de sua mgica, para tornar seu processo dedesenvolvimento o mais rpido e simples possvel.

    http://www.sitepoint.com/best-php-framework-2015-sitepoint-survey-results/

  • InstalaoFazer a instalao do Laravel algo extremamente simples. Basicamente, como instalar qualqueroutro framework PHP, porm, para isso, voc dever trabalhar com o Composer.No sei se alguma vez voc j ouviu falar no composer. Ele uma biblioteca escrita em PHP quetem o objetivo de fazer o gerenciamento de dependncias de nossas aplicaes.Instalar o composer uma tarefa extremamente simples:

    Acesse: http://getcomposer.org/download Faa o download da biblioteca Pronto, voc ter um arquivo chamado composer.phar em sua mquina pronto para uso.

    Minha dica de que voc deixe esse arquivo registrado em suas variveis de ambiente, para que aodigitar apenas o comando composer em seu terminal, ele j seja executado diretamente.Uma vez que voc possua o composer baixado / instalado em seu computador, instalar o Laravel uma tarefa extremamente simples.

    Instalao via Laravel InstallerO Laravel possui uma biblioteca que facilita muito sua vida para a criao de novos projetos Laravel,ns a chamamos de Laravel Installer.Para instal-la, voc dever utilizar o seguinte comando via composer:

    1 composer global require "laravel/installer=~1.1"

    Feito isso, no se esquea de adicionar as bibliotecas do composer em suas variveis de ambientetambm. O caminho normalmente :

    1 ~/.composer/vendor/bin

    Agora, basta simplesmente rodar o comando para criar um novo projeto Laravel:

    http://getcomposer.org/download

  • Instalao 6

    1 laravel new NomeDoProjeto

    Instalao direta via composerUma outra forma de voc instalar um novo projeto Laravel, rodando o seguinte comando viacomposer:

    1 composer create-project laravel/laravel --prefer-dist

    Com isso o Laravel ser interamente clonado e configurado em seu computador, estando pronto parauso.

    Executando Laravel pela primeira vezUma vez que voc executou um dos passos anteriores e se voc possui no mnimo a verso 5.4 doPHP, basta entrar no diretrio do projeto criado e executar o servidor embutido do PHP rodando ocomando:

    1 cd laravel2 php -S localhost:8000 -t public/

    Ou simplesmente digitar o comando abaixo:

    1 php artisan serve

    Prontinho! Laravel 5 rodando.

  • A estrutura do LaravelNesse captulo, vou lhe apresentar a estrutura geral do funcionamento bsico do framework, bemcomo sua estrutura de pastas e arquivos que so bsicos necessrios para que voc consiga sairdesenvolvendo.

    Estrutura de pastas e arquivosQuem um dia j chegou a instalar o Laravel 5, provavelmente deve ter tomado um ligeiro susto pelagrande quantidade de arquivos e pastas que temos que entender para conseguir trabalhar com oframework.De qualquer forma, para comear, voc no precisa entender necessariamente todas as pastas earquivos de configurao, nesse ponto, apresentarei apenas os que acho mais importantes nessemomento.

    Estrutura de pastas

    vendor

    A pasta vendor, gerada automaticamente pelo composer. Nessa pasta voc encontrar todas asbibliotecas necessrias para rodar o framework. Voc nunca dever mexer nesse diretrio, uma vezque ele gerenciado automaticamente pelo prprio composer.

    public

    A pasta public, uma das mais importantes da aplicao, uma vez que ela o DocumentRootdo nosso sistema, ou seja, todas as requisies sempre cairo diretamente nela, dessa forma, issogarantir que quem acessa nossa aplicao, jamais ter acesso a pastas do mesmo nvel que a public.Alm disso, a pasta public a responsvel por servir, publicamente, todos os nossos assets para omundo exterior, ou seja, no final das contas, todos os javascripts, css, fonts, imagens, etc deveroestar na pasta public; sem contar que o arquivo index.php tambm ficar armazenado nela.

    config

    Pelo fato do Laravel ser um framework com diversos tipos de funcionalidades, o mesmo necessitade uma estrutura que nos permita fazer as mais diversas configuraes de seus componentes. Nesseponto, a pasta config a responsvel por armazenar os mais diversos arquivos de configurao doframework, desde configuraes de banco de dados, envio de emails, cache, etc.

  • A estrutura do Laravel 8

    storage

    Toda vez que voc necessitar gravar qualquer arquivo dentro do Laravel, a pasta storage ser muitotil. Ela tem o objetivo de armazenar os mais diversos arquivos para uso interno do framework,como arquivos de cache, banco de dados (sqlite por exemplo), entre outros.

    databases

    Na pasta databases voc encontrar os recursos necessrios para que voc possa trabalhar com suasmigrations e seeders. Veremos nos prximos captulos maiores detalhes sobre esses recursos.

    tests

    O Laravel j vem totalmente configurado para que voc consiga rodar seus testes automatizados. na pasta tests que seus scripts de testes devero ficar armazenados.

    app

    Essa a pasta principal de nossa aplicao. Basicamente, grande parte do cdigo que digitaremosem nosso projeto estar dentro dela. A pasta app, possui muitas subpastas, nesse ponto, pretendoexplic-las apenas quando tivermos a necessidade de fazer uso das mesmas.

    Arquivos

    composer.json e composer.lock

    Esses dois arquivos so utilizados pelo composer para gerenciar todas as dependncias do projeto:como biblioteca de terceiros e principalmente as do prprio Laravel.

    .env e .env.example

    O Laravel, trabalha com uma lib chamada de DotEnv. Ela tem o objetivo de guardar todas asinformaes de configurao de seu ambiente, como user, senha de banco de dados, informaesde debug, entre outros. O arquivo .env nunca dever fazer parte do seu controle de verso, uma vezque ele guarda informaes especficas de um ambiente, logo, para fazer uso dele, basta copiar oarquivo .env.example para .env e fazer suas configuraes locais.

    artisan

    O Artisan ser o seu melhor amigo na jornada com o Laravel, ele lhe dar acesso por linha decomando para executar diversos tipos de tarefas, como: criar um Model, Controller, Providers,Commands, Migrations, etc. Com certeza voc utilizar bastante esse camarada.

  • A estrutura do Laravel 9

    gulpfile.js

    O gulpfile.js o responsvel por definir quais as tarefas que nosso asset manager chamado de Elixirexecutar.

    package.json

    O package.json o arquivo responsvel por definir as dependncias de mdulos Node.js que nossaaplicao possui. Por padro, ele vem com duas dependncias: a do Gulp e a do Laravel-elixir.

    phpspec.yml

    O phpspec.yml o arquivo de configurao de um framework de testes que tambm suportadopelo Laravel.

    phpunit.xml

    O phpunit.xml o arquivo responsvel por fazer todas as configuraes bsicas para que voctambm consiga rodar seus testes desenvolvidos utilizando o PHPUnit.

    Ciclo de vida de uma aplicao LaravelQuando acessamos uma aplicao Laravel, voc deve imaginar que muita coisa deve acontecer porbaixo dos panos do framework.Explicarei brevemente, quais so os principais pontos que voc deve conhecer quando fazemos umarequisio em uma aplicao.

    Tudo passa pelo index.phpQuando fazemos uma requisio em uma aplicao Laravel, todas as URLs acessadas so apontadasdiretamente para um nico arquivo, o index.php, que fica localizado na pasta public.Exemplo de um index.php padro do Laravel 5:

  • A estrutura do Laravel 10

    1

  • A estrutura do Laravel 11

    1 $response = $kernel->handle(2 $request = Illuminate\Http\Request::capture()3 );

    O mtodo handle, simplesmente recebe uma requisio (Request) e nos devolve uma Response, queser entregue. Apenas isso.

    O processamento Interno de uma RequestUma vez que o Kernel recebeu a requisio, e tudo j foi inicializado, o framework analisar arequisio para definir para qual recurso ela dever encaminh-la. Voc deve estar pensando: Mascomo ele faz isso?O Laravel, no muito diferente de outros frameworks, trabalha com conceito de Rotas. Para tentardeixar a explicao mais didtica, tentarei dar um exemplo fictcio, vamos l:

    Exemplo

    Vamos supor que nossa aplicao Laravel acaba de receber uma requisio com as seguintesinformaes:

    1 GET /produtos HTTP/1.12 Host: www.meusite.com.br

    Podemos perceber na requisio HTTP, simplificada acima, que a mesma foi enviada utilizando omtodo GET, solicitando informaes de nosso recurso /produtos no host www.meusite.com.br.Resumindo, algum acessou o endereo: http://www.meusite.com.br/produtosA funcionalidade de rotas do Laravel, simplesmente faz o mapeamento de qual mtodo e recurso foisolicitado por uma requisio (nesse exemplo: Mtodo GET e o recurso de produtos), e simplesmenteaponta tal requisio para onde definirmos (pode ser uma funo, controller, etc).Segue um exemplo simples da utilizao da funcionalidade de rotas do Laravel, processando arequisio que citamos como exemplo:

    1 $app->get('produtos', function() {2 return "Meus Produtos";3 });

    Perceba que nesse caso, estamos dizendo que todas todas as requisies com o mtodo GET quetentarem acessar o recurso /produtos, sero diretamente direcionadas para uma funo annimaque retornar como response o valor: Meus Produtos.Nos prximos captulos desse livro, veremos mais a fundo como trabalhar com Rotas. O exemploacima, foi apenas para demonstrar o funcionamento bsico do ciclo de vida do framework.

  • Configurando sua aplicao LaravelAlterando o Namespace de sua aplicaoNo momento em que voc navegar pelas pastas e arquivos criados pelo Laravel, voc perceber queo Namespace padro gerado, automaticamente, pelo framework para voc utilizar ter o nome deApp.O grande ponto, que se em algum momento voc resolver distribuir ou reaproveitar partes docdigo de sua app, voc ter uma grande chance de sofrer colises de nomes de suas classes, umavez que o Namespace App totalmente genrico e muito provavelmente voc encontrar aplicaespor a utilizando tal nome.Nesse ponto, o Laravel, nos prov um recurso, atravs do Artisan, para que possamos alterar onamespace padro de nossa aplicao. extremamente simples realizar essa tarefa. Veja abaixo:

    1 php artisan app:name SeuNameSpace

    Executando tal comando, o Laravel, far automaticamente a mudana em todos os namespaces como padro App em sua aplicao para o novo namespace que voc definiu.

    Configurando banco dadosPor padro, o Laravel te da a possibilidade de trabalhar com os seguintes sistemas de gerenciamentode banco de dados:

    Sqlite MySQL PostgreSQL SQL Server Redis *

    Se voc abrir o arquivo que est localizado em: app/config/database.php, voc perceber que j existeum array pr-definido com todas as configuraes necessrias para que possamos ativar a utilizaode quaisquer SGDBs.

  • Configurando sua aplicao Laravel 13

    Pontos para voc ficar atento

    Key default

    Ser nessa key que voc definir qual SGDB sua aplicao rodar, nesse ponto, voc poder escolherentre:

    sqlite mysql pgsql sqlsrv

    Por outro lado, voc ver que nos arrays de configurao de cada banco de dados, j temos um valorpadro, pr-definido, para user, password, host, etc; todavia, se voc notar, perceber que temostambm uma funo chamada: env os envolvendo.Veja um exemplo abaixo:

    1 'connections' => [23 'sqlite' => [4 'driver' => 'sqlite',5 'database' => storage_path().'/database.sqlite',6 'prefix' => '',7 ],89 'mysql' => [10 'driver' => 'mysql',11 'host' => env('DB_HOST', 'localhost'),12 'database' => env('DB_DATABASE', 'forge'),13 'username' => env('DB_USERNAME', 'forge'),14 'password' => env('DB_PASSWORD', ''),15 'charset' => 'utf8',16 'collation' => 'utf8_unicode_ci',17 'prefix' => '',18 'strict' => false,19 ],2021 'pgsql' => [22 'driver' => 'pgsql',23 'host' => env('DB_HOST', 'localhost'),24 'database' => env('DB_DATABASE', 'forge'),

  • Configurando sua aplicao Laravel 14

    25 'username' => env('DB_USERNAME', 'forge'),26 'password' => env('DB_PASSWORD', ''),27 'charset' => 'utf8',28 'prefix' => '',29 'schema' => 'public',30 ],3132 'sqlsrv' => [33 'driver' => 'sqlsrv',34 'host' => env('DB_HOST', 'localhost'),35 'database' => env('DB_DATABASE', 'forge'),36 'username' => env('DB_USERNAME', 'forge'),37 'password' => env('DB_PASSWORD', ''),38 'prefix' => '',39 ],4041 ],42 ]

    A funo env, tem uma simples e tima utilidade: Ela verifica se a key solicitada possui um valorem nosso arquivo .env, que fica na raiz do projeto. Caso a key exista, ela pegar o valor dessa key,caso contrrio, ela utilizar o valor padro que passado em seu segundo parmetro.Nesse ponto, tudo que precisamos fazer, definirmos as configuraes de nossos dados sensveiscomo: host, user, password, etc, em nosso arquivo .env, que automaticamente o Laravel, vai utiliz-las para estabelecer a conexo com o banco de dados.

    Sempre lembrando que o arquivo .env, jamais dever fazer parte de seu controle de verso.

    Configurando envio de emailsUma vez que voc entendeu o conceito de como fazer as configuraes de banco de dados no Laravel,o mesmo se aplica para as configuraes de envio de email.Basta abrir o arquivo app/config/mail.php e verificar quais keys de configurao esto sendoutilizadas por padro pela a funo env, nesse caso, basta colocar seus dados sensveis em relao asconfiguraes de email no arquivo .env de seu projeto.

    Configurao do ambienteUm item que no podemos deixar passar, sos as configuraes especficas de seu ambiente Laravel.

  • Configurando sua aplicao Laravel 15

    Veja um exemplo de pontos que voc tem que se atendar e jamais deixar de configurar, corretamente,de acordo com o ambiente em que sua aplicao est rodando, ou seja: desenvolvimento, produo,etc.

    1 APP_ENV=local2 APP_DEBUG=true3 APP_KEY=SomeRandomString

    APP_ENVPerceba que na Key APP_ENV, determinamos em qual ambiente a aplicao est sendo executada,ou seja, local, production, etc.

    APP_DEBUGJ a key APP_DEBUG extremamente til estar setada para true apenas quando estamos emmododesenvolvimento, pois dessa forma, todo erro que recebermos, poderemos ter todo seu tracing,facilitando a vida para entender o que realmente deu errado.

    Nunca esquea de deixar a key APP_DEBUG=false quando for colocar a aplicao emproduo.

    APP_KEYA key APP_KEY extremamente importante para definir sua aplicao Laravel como nica, tendouma chave para auxiliar nos processos de gerao de tokens contra CSRF, Salt para o password hash,encriptao de cookies, sessions, etc.Normalmente quando voc instala o Laravel via composer, ele j preenche uma string randmicana sua APP_KEY, mas sempre bom realmente verificar se esse ponto realmente foi executado comsucesso.

    ConcluindoAo acessar a pasta app/config do Laravel, voc ver uma infinidade de arquivos que configuramfuncionalidades especficas no framework.O conceito sempre ser o mesmo. Basta realizar as configuraes das funcionalidades que realmentevoc ter a necessidade de utilizar.No decorrer do livro, se precisarmos utilizar um recurso que ainda no configuramos, com certezavoltaremos nessa pasta app/config.

  • Trabalhando com Rotas, Controllers eViewsIntroduoSei que at o momento, voc teve que acompanhar muita teoria para entender:

    O Contexto atual do Laravel no mundo PHP Seu ciclo de vida Instalao Configuraes iniciais

    A partir desse captulo, colocaremos um pouco mais a mo na massa para que voc possa comeara sentir a grande flexibilidade e facilidade que o Laravel possui para desenvolver aplicaes.

    Voltando s RotasQuando nossa aplicao recebe uma requisio, o kernel do Laravel tem a funo de inicializar seusprincipais componentes para que ento possamos tratar o request.Parte desse tratamento do request realizado pelas rotas, todavia, temos N maneiras detrabalharmos e manipularmos tais rotas.Nesse captulo, apresentarei apenas duas formas de trabalharmos com rotas, para que possamoscomear a ter as primeiras interaes com nossos Controllers e Views.

    Rotas e funes annimasQuando definimos uma rota, podemos fazer com que, uma vez que ela de um match com a requestsolicitada, ela execute uma funo.

    O arquivo de configurao de rotas do Laravel, pode ser encontrado em: app/Http/rou-tes.php.

    Exemplo:

  • Trabalhando com Rotas, Controllers e Views 17

    1 //app/Http/routes.php23 Router::get('produtos', function() {4 return "Ol mundo";5 });

    Perceba que nesse caso, quando algem acessar o endereo: /produtos, via mtodo GET, receber umretorno instantneo do Laravel, com o nosso famoso Ol mundo, ou seja, nossa funo annimaser imediatamente executada.Por outro lado, muitas vezes, queremos encaminhar essa requisio para um camarada que possafazermelhor a intermediao entre as camadas (responsabilidades) de nossa aplicao. Normalmenteesse camarada o nosso Controller.*Ainda nesse captulo, aprofundaremos um pouco mais sobre controllers. *Por hora, entenda o Controller como uma classe que possui mtodos; e no caso de nossas rotas,podemos fazer com que elas encaminhem nossa requisio exatamente para uma determinada classe(controller) e para um determinado mtodo (action).Vejamos um exemplo:1 Router::get('produtos','ProdutosController@index');

    No exemplo acima, estamos dizendo que quando recebermos uma request para a URI /produtos,com o mtodo HTTP GET, executaremos o mtodo index de nossa classe ProdutosController.

    ControllersQuando falamos de controllers, estamos falando de uma camada de nossa aplicao que possui umaresponsabilidade muito bem definida: Ser o intermediador, ou seja, ele recebe a requisio, se houvernecessidade ele pode chamarmodels para consultar ou mesmo persistir dados e depois definir comoa response ser retornada.Nesse ponto, podemos por exemplo retornar um HTML simples, um json, ou mesmo, definir umaView (outra camada de nossa aplicao), que ficar responsvel por renderizar o cdigo HTML a serexibido ao usurio final.Nesse captulo, vamos focar em apenas receber uma requisio em nosso controller e encaminhar oresponse de trs maneiras.

    1. HTML simples como retorno2. Json3. Apontamento para uma View

    Perceba que estamos partindo de que nossa Rota esteja nos apontando para: Produtos-Controller@index, ou seja, classe: ProdutosController, mtodo: index.

  • Trabalhando com Rotas, Controllers e Views 18

    Retornando um HTML Simples1

  • Trabalhando com Rotas, Controllers e Views 19

    Para que voc no precise ficar misturando o cdigo HTML dentro de sua classe de controller, comovimos no exemplo Retornando um HTML Simples, voc pode apontar o retorno para a camadaView do Laravel seja chamada e renderize o HTML para voc.Alm disso, voc contar com o recurso da template engine chamada de Blade, que prov uma sriede facilidades, que aos poucos demostrarei para voc.Vamos ao cdigo:1

  • Trabalhando com Rotas, Controllers e Views 20

    1 2 3 Produtos4 56 78 Ol {{ $nome }}910 11

    Nesse caso, estamos utilizando uma tag especfica do Blade para imprimir o valor de uma varavel:{{ $home }}.Nos prximos captulos, veremos como podemos fazer chamadas mais complexas dentro de nossoscontrollers e exibir informaes em nossas views, utilizando o Blade, com mais detalhes.Por hora, ficarei muito contente se voc conseguindo entender esse pequeno fluxo que fizemos emuma aplicao Laravel, desde as suas rotas at a exibio de um contedo a partir de uma view.

  • ModelsIntroduoQuando falamos do padro M-V-C, estamos falando em separao de responsabilidades de diversosparticipantes de nossa aplicao.No captulo anterior, apresentei brevemente a utilizao do C (Controller) e do V (View).Nesse captulo, focaremos em entender os conceitos bsicos sobre o M (Model), e como poderemosfazer a utilizao e integrao dessa camada com as outras duas.

    Falando sobre ModelsDiferentemente do que muita gente pensa, o conceito de Models bem abrangente. Quando falamosde Models, estamos falando de um participante que ter o objetivo de fazer qualquer consumo etransao de dados em nossa aplicao.Vamos imaginar que desenvolveremos uma simples aplicao que far a exibio de diversasinformaes sobre tweets.Nesse caso, quem far o consumo e gerenciamento das informaes (dados) dos tweets para nossaaplicao, ser exatamente nossa camada Model.Entenda, quando falamos em Model, falamos em dados!Quando falamos na camada de Model, muita gente j faz a associao direta de que so os Modelsque cuidam diretamente da parte de banco de dados de nossa aplicao.Na realidade, a parte de banco de dados, apenas uma, das mais diversas fontes de dados que nossaModel pode gerenciar, todavia, como extremamente comum termos bancos de dados atrelados asnossas aplicaes, a associao entre Models e Banco de dados fica, muito mais evidente do queoutras fontes de dados.De qualquer forma, sempre tenha emmente que quando estamos falando deModels, estamos falandode qualquer tipo de fonte de dados, como:

    Webservice / API Banco de dados Arquivos textos entre outros

  • Models 22

    Models no LaravelNormalmente, quando estamos falando de Models no Laravel, estamos falando de como faremosacesso as informaes de banco de dados em nossa aplicao, bem como faremos a disponibilizaoe transaes com tais informaes.O Laravel possui um ORM chamado de Eloquent, o qual faz a relao direta entre as nossas classesde Model com nossas tabelas de banco de dados.Acredito que o grande goal do Eloquent, a sua excepcional facilidade de uso, nesse ponto, mostrareibrevemente como voc poder fazer uso dessa poderosa ferramenta.

    Configurando um banco de dadosComo quase tudo no Laravel, fazer a configurao de um banco de dados algo extremamentesimples. Basicamente, voc ter de definir qual ser o SGDB a ser utilizado e passar as informaesde acesso e/ou credenciais.O arquivo responsvel por conter todos os SGDBs pr-configurados no Laravel :config/database.phpEle composto por um array, onde facilmente poder ser modificado.Segue um exemplo de uma pequena parte desse arquivo:

    1 return [23 /*4 |--------------------------------------------------------------------------5 | Default Database Connection Name6 |--------------------------------------------------------------------------7 |8 | Here you may specify which of the database connections below you wish9 | to use as your default connection for all database work. Of course10 | you may use many connections at once using the Database library.11 |12 */1314 'default' => 'mysql',1516 /*17 |--------------------------------------------------------------------------18 | Database Connections19 |--------------------------------------------------------------------------

  • Models 23

    20 |21 | Here are each of the database connections setup for your application.22 | Of course, examples of configuring each database platform that is23 | supported by Laravel is shown below to make development simple.24 |25 |26 | All database work in Laravel is done through the PHP PDO facilities27 | so make sure you have the driver for your particular database of28 | choice installed on your machine before you begin development.29 |30 */3132 'connections' => [3334 'sqlite' => [35 'driver' => 'sqlite',36 'database' => storage_path().'/database.sqlite',37 'prefix' => '',38 ],3940 'mysql' => [41 'driver' => 'mysql',42 'host' => env('DB_HOST', 'localhost'),43 'database' => env('DB_DATABASE', 'forge'),44 'username' => env('DB_USERNAME', 'forge'),45 'password' => env('DB_PASSWORD', ''),46 'charset' => 'utf8',47 'collation' => 'utf8_unicode_ci',48 'prefix' => '',49 'strict' => false,50 ],51 ]

    Perceba que temos um key nesse array chamada de default. Essa key a responsvel por definir qualser o banco de dados padro a ser utilizado em nossa aplicao.Como voc pode perceber, o padro trazido pelo Laravel o MySQL.O outro ponto que voc deve notar, que temos uma key chamada MySQL, onde podemos informartodas as configuraes de acesso ao banco de dados, contudo, se voc perceber, o valor das principaisinformaes esto setados utilizando uma funo chamada env, por exemplo:

  • Models 24

    1 'host' => env('DB_HOST', 'localhost'),

    Isso significa que o Laravel por padro acessar nosso arquivo .env e buscar pela key DB_HOST,caso ele no a encontre, o valor padro para essa informao ser localhost.Lembre-se, o arquivo .env, tem o objetivo de armazenar as informaes sensveis de ambiente denossa aplicao, nesse ponto, podemos ter algo desse tipo ao abrirmos esse arquivo.

    1 DB_HOST=localhost2 DB_DATABASE=homestead3 DB_USERNAME=homestead4 DB_PASSWORD=secret

    Ser exatamente nesse arquivo que voc entrar com as informaes de acesso ao seu banco dedados.

    Utilizando o sqlite como exemploApenas para fins didticos, utilizaremos um banco sqlite para trabalhar com os exemplos desse livro,logo, realizarei apenas dois pequenos passos para ter meu banco de dados configurado.

    1. Mudar a chave default do meu arquivo database.php para: sqlite2. Criar um arquivo em banco chamado database.sqlite dentro da pasta storage da aplicao

    Criando nosso primeiro ModelCriar um model no Laravel algo extremamente simples, basta criar uma classe que estenda de:IlluminateDatabaseEloquentModel, por outro lado, o framework nos traz diversas facilidades paraque criemos nossos models, utilizando a linha de comando com o Artisan.Basta rodar o comando:

    1 php artisan make:model Produto

    E voc ter o seguinte resultado:

    1 Model created successfully.2 Created Migration: 2015_04_20_213916_create_produtos_table

    O Artisan, acaba de criar dois arquivos:

    Produto.php, dentro de nossa pasta app 2015_04_20_213916_create_produtos_table.php, dentro da pasta database/migrations

  • Models 25

    Falando brevemente sobre MigrationsO Laravel possui o recurso demigrations, onde tem o objetivo de gerenciar cada mudana estruturalde nosso banco de dados, ou seja, para cada tabela, coluna, ndice, criados em nosso banco de dados,podemos ter uma migration para realizar essa operao de forma automtica.Um ponto bem interessante sobre migrations, que temos exatamente cada verso da estrutura denossa banco de dados, logo, se sentirmos a necessidade, podemos facilmente dar um roll back.Seguinte nosso exemplo do model criado: Produto, a migration 2015_04_20_213916_create_produ-tos_table foi criada:

    1

  • Models 26

    Se voc perceber, temos dois mtodos principais: up() e down(). O mtodo up executado quando amigration rodada, j o mtodo down, executado cada vez que damos um roll back, nessa mesmamigration.Nesse nosso caso, perceba que a o mtodo up est sendo responsvel por uma tabela chamada deprodutos.Por padro, tal tabela possuir uma coluna: ID, auto_increment e outras duas colunas referentes adata / hora de insero e alterao de um registro (created_at e updated_at).Para que possamos seguir com nosso exemplo, adicionarei mais duas colunas em nossa tabelaprodutos:

    1. nome, com tamanho 2552. descricao, do tipo text

    1 public function up()2 {3 Schema::create('produtos', function(Blueprint $table)4 {5 $table->increments('id');6 $table->string('nome', 255);7 $table->text('descricao');8 $table->timestamps();9 });10 }

    Feita essa nossa alterao, basta apenas rodarmos os seguinte comandos via Artisan:

    1 php artisan migrate:install2 php artisan migrate

    O comando migrate:install, cria uma tabela em nosso banco de dados para poder gerenciar nossasmigrations.J o comando migrate, executa todas as migrations disponveis em nossa aplicao.Pronto! J temos uma tabela de banco de dados criada, pronta para ser utilizada em conjunto comnosso Model Produto.

    Brincando com nosso ModelSe voc abrir o arquivo de nosso Model, localizado em: appProduto.php, voc ter o seguinteresultado:

  • Models 27

    1

  • Models 28

    1 >>> Produto::all();2 => [3 {4 id: "1",5 nome: "Livro de Laravel 5",6 descricao: "Descricao do livro",7 created_at: "2015-04-20 22:01:57",8 updated_at: "2015-04-20 22:01:57"9 }10 ]

    Ao chamarmos estaticamente o mtodo all() de nosso model, perceba que recebemos uma coleode modelos Produto (Eloquent), que nesse caso, o produto que acabamos de inserir no banco dedados.Se quisermos, podemos selecionar apenas o Produto desejado, utilizando o mtodo find().

    1 >>> $livro = Produto::find(1);2 => {3 id: "1",4 nome: "Livro de Laravel 5",5 descricao: "Descricao do livro",6 created_at: "2015-04-20 22:01:57",7 updated_at: "2015-04-20 22:01:57"8 }

    Nesse caso, o Model Produto, com o ID 1, foi atribudo em nossa varivel $livro.Podemos agora, fazer modificaes nesse objeto e persisti-las novamente no banco de dados:

    1 >>> $livro->descricao = "O melhor livro de Laravel, ever!";2 => "O melhor livro de Laravel, ever!"3 >>> $livro->save();4 => true

    Protinho, mudamos facilmente a descrio de nosso produto.Vamos listar novamente os produtos, para ver se nossa modificao foi refletida:

  • Models 29

    1 >>> Produto::all();2 => [3 {4 id: "1",5 nome: "Livro de Laravel 5",6 descricao: "O melhor livro de Laravel, ever!",7 created_at: "2015-04-20 22:01:57",8 updated_at: "2015-04-20 22:10:48"9 }10 ]

    Pronto, podemos ver que os dados foram alterados no banco de forma totalmente descomplicada.

    Utilizando nosso Model no ControllerAgora que j demos nossos primeiros passos com nosso Model, vamos exibir tais informaes nobrowser do usurio, seguindo exatamente o fluxo que vimos no captulo anterior, todavia, aplicandoagora nossos conhecimentos sobre Models.

    1 // app/Http/Controllers/ProdutosController.php2

  • Models 30

    1 // resources/views/produtos.blade.php23 4 5 Produtos6 7 89 Produtos1011 12 13 ()14 15 1617 18

    Com isso teremos nosso resultado to desejado, uma listagem dos dados do banco de dados em nossaview:

    Listagem de Produtos

    Agora perceba que utilizamos as tags do PHP para fazermos o foreach; para facilitar nossa vida,podemos utilizar o recurso de foreach do prprio Blade para facilitar.

  • Models 31

    1 2 3 Produtos4 5 67 Produtos89 10 @foreach($produtos as $produto)11 {{ $produto->nome }} ({{ $produto->descricao }})12 @endforeach13 1415 16

    Perceba que tivemos o mesmo resultado, todavia com um cdigo muito mais limpo.

  • Rumo ao primeiro CRUDNormalmente, quem j possui uma certa experincia com desenvolvimento web, provavelmente jest familiarizado com o termo CRUD, que significa: Create, Retrieve, Update e Delete.O CRUD nada mais do que um termo utilizado representando as principais operaes que podemosrealizar em uma entidade, ou seja, Criar, Listar, Alterar e Remover dados.

    Listando nossos ProdutosNo captulo anterior, quando entendemos os conceitos iniciais sobre Models, fizemos uma simpleslistagem de nossos produtos. Agora, iremos preparar tal listagem para que possamos executar nossasprincipais operaes (CRUD).

    Herdando um templateAcredito que voc j deva ter se antecipado e feito a seguinte pergunta: Como podemos aproveitarum template (view) padro para todas as nossas pginas, sem que precisemos ficar duplicando atodo momento nosso HTML que nos serve como base de nossa aplicao?A resposta para essa pergunta : Blade.Essa uma das grandes vantagens de voc poder utilizar o Blade. O Blade possibilita que voc herdesuas views de um template principal a fim de facilitar o reaproveitamento de cdigo.Vamos ver como isso funciona na prtica.Hoje, nossa view: produtos.blade.php encontra-se da seguinte forma:

    1 2 3 Produtos4 5 67 Produtos89 10 @foreach($produtos as $produto)11 {{ $produto->nome }} ({{ $produto->descricao }})

  • Rumo ao primeiro CRUD 33

    12 @endforeach13 1415 16

    Nossa idia, utilizarmos um template padro que o Laravel j nos trs para faciltiar nosso trabalho.

    Apenas lembrando que voc tem toda a possibilidade de customizar e criar seu prpriotemplate padro para sua aplicao.

    Se voc analisar a pasta resources/views, encontrar um arquivo chamado app.blade.php, essearquivo o template padro que o Laravel 5 nos trs para que possamos utilizar como base denossa aplicao.Ao abrir esse arquivo, quase no final, voc encontrar a seguinte chamada:@yield(content). Issosignifica que se criarmos em nossa view, uma @section com o nome de content, e herdarmos otemplate app.blade.php, todo o contedo de nossa view aparecer exatamente no local onde temosa chamada: @yield(content).Para facilitar o entendimento, faamos isso na prtica:

    1 // produtos.blade.php2 @extends('app')34 @section('content')5 6 Produtos7 8 @foreach($produtos as $produto)9 {{ $produto->nome }} ({{ $produto->descricao }})10 @endforeach11 12 13 @endsection

    Perceba que utilizamos o comando @extends do Blade para fazer com que nossa view produ-tos.blade.php possa herdar o template app.blade.php.Em seguida, utilizamos a chamada @section(content) para definir que tudo que estiver dentrodela, ser aplicado exatamente aonde temos a chamada@yield(content) no template app.blade.php.Veja o resultado abaixo:

  • Rumo ao primeiro CRUD 34

    Listagem de produtos herdando template app.blade.php

    Fazendo a listagem em uma tabelaAgora que j temos um template base para toda nossa aplicao, faremos a listagem dos produtosem uma tabela afim de facilitar a visualizao, bem como adicionar as aes que poderemos realizarem cada um dos registros.

    1 @extends('app')23 @section('content')4 5 Produtos67 8 9 10 ID11 Nome12 Descrio13 Ao14 15 16 1718 @foreach($produtos as $produto)

  • Rumo ao primeiro CRUD 35

    19 20 {{ $produto->id }}21 {{ $produto->nome }}22 {{ $produto->descricao }}23 24 25 @endforeach2627 28 29 30 @endsection

    Listagem de produtos em uma tabela

    Criando novos produtosAgora que j temos nossa pgina de listagem de produtos devidamente formatada e utilizando umtemplate base, iniciaremos o processo para criar novos produtos no sistema.

    Criando pgina de CreateNosso principal ponto nesse momento criar uma action que chamaremos de create para quepossamos apontar a seguinte rota para ela: produtos/create.

  • Rumo ao primeiro CRUD 36

    1 // app/Http/Controllers/ProdutosController.php23

  • Rumo ao primeiro CRUD 37

    1 // resources/views/produtos/create.blade.php2 @extends('app')34 @section('content')5 6 Novo Produto78 9 @endsection

    Falta registrarmos uma nova rota apontando: produtos/create para essa nossa nova action.No arquivo routes.php faremos o seguinte registro:

    1 //app/Http/routes.php23 // ...4 Route::get('produtos/create','ProdutosController@create');5 // ...

    Ao acessarmos a aplicao com a rota: produtos/create, teremos o seguinte resultado:

    Listagem de produtos em uma tabela

    Trabalhando com formulrios no Laravel

    Instalando o Illuminate/Html

    J temos nossa pgina produtos/create pronta e preparada para receber nosso formulrio.Voc possui duas opes nesse momento:

  • Rumo ao primeiro CRUD 38

    1. Criar manualmente seus formulrios HTML2. Utilizar a ajuda do componente Illuminate/Html do Laravel.

    Nesse nosso caso, utilizaremos a segunda opo para termos mais agilidade no processo de criaodos formulrios.A idia instalarmos o pacote: Illuminate/HtmlPara instal-lo, basta o rodar o seguinte comando via composer. Voc ter o resultado similar aoexibido logo abaixo:

    1 composer require illuminate/html2 Using version ~5.0 for illuminate/html3 ./composer.json has been updated4 Loading composer repositories with package information5 Updating dependencies (including require-dev)6 - Installing illuminate/html (v5.0.0)7 Loading from cache89 Writing lock file10 Generating autoload files11 Generating optimized class loader

    Teremos que registrar esse pacote como um Service Provider (falaremos mais sobre ServiceProviders nos prximos captulos), dessa forma o Laravel poder encontrar esses componentes.Para fazer isso, adicione a seguinte linha ao final do array providers dentro do arquivo: con-fig/app.php.

    1 // config/app.php23 providers' => [4 // Outros providers5 'Illuminate\Html\HtmlServiceProvider'

    Tambm, no mesmo arquivo, voc ter que adicionar duas linhas no array de aliases:

    https://github.com/illuminate/html

  • Rumo ao primeiro CRUD 39

    1 // config/app.php2 'aliases' => [3 // Outros aliases4 'Form' => 'Illuminate\Html\FormFacade',5 'Html' => 'Illuminate\Html\HtmlFacade',

    Pronto! Agora, poderemos criar nossos formulrios de uma forma muito rpida e produtiva.

    Criando formulrio

    Uma vez que j temos o pacote IlluminateHtml instalado, podemos abrir nosso arquivo cre-ate.blade.php e fazermos um rpido teste:

    1 //resources/views/protudos/create.blade.php2 @extends('app')34 @section('content')5 6 Novo Produto78 {!! Form::open() !!}910 {!! Form::close() !!}1112 13 @endsection

    Ao acessarmos nossa aplicao na rota produtos/create, aparentemente nada ter mudado, porm,quando inspecionarmos o cdigo fonte, poderemos perceber que os seguintes itens foram adiciona-dos:

    1 3 5

    O Laravel, automaticamente, criou as tags e ainda um elemento hidden como um token paraproteger nosso formulrio contra CSRF.Vamos agora adicionar os outros itens para nosso formulrio ficar completo:

  • Rumo ao primeiro CRUD 40

    1 @extends('app')23 @section('content')4 5 Novo Produto67 {!! Form::open() !!}89 1011 12 {!! Form::label('nome', 'Nome:') !!}13 {!! Form::text('nome', null, ['class'=>'form-control']) !!}14 1516 1718 19 {!! Form::label('descricao', 'Descrio:') !!}20 {!! Form::textarea('descricao', null, ['class'=>'form-control']) !!}21 2223 24 {!! Form::submit('Criar Produto', ['class'=>'btn btn-primary']) !!}25 2627 {!! Form::close() !!}2829 30 @endsection

    Perceba que com a simples utilizao das tags mostradas acima, conseguimos o seguinte resultadoem nosso formulrio:

  • Rumo ao primeiro CRUD 41

    Formulrio de incluso de produto

    A action store

    Agora que j temos nosso formulrio criado, precisamos criar uma nova action que ser responsvelpor receber a request do nosso form e chamar nosso Model Produto para persistir os dados no banco.Tambm precisaremos registrar uma nova rota: produto/store.Vamos l:

    1 // app/Http/routes.php23 Route::post('produtos/store','ProdutosController@store');

    Perceba que estamos utilizando Route::post, uma vez que o formulrio ser enviado via omtodo HTTP POST e no GET.

    Tambm temos que realizar um pequeno ajuste em nosso arquivo create.blade.php para apontar oform para a nossa url produtos/store.

  • Rumo ao primeiro CRUD 42

    1 {!! Form::open(['url'=>'produtos/store']) !!}

    Agora, vamos criar nossa action store:

    1

  • Rumo ao primeiro CRUD 43

    Erro ao submeter o formulrio

    O Laravel trabalha com uma pequena proteo em seus models contra Mass Assigment, ou seja,quando atribuimos dados em massa, como no caso de termos passado todas as informaes do formdiretamente.Nesse caso, para permitir que possamos inserir os dados do form diretamente, temos que configurarnosso Model para aceitar a atribuio em massa de nossos dois campos: nome, descricao. Para isso,basta adicionar um atributo chamado $fillable na classe de nosso model Produto.1 // app/Produto.php2

  • Rumo ao primeiro CRUD 44

    Validando dadosAgora que j temos nosso formulrio possibilitando a criao de novos registros, temos que podervalidar as informaes que esto sendo enviadas atravs das requisies.O Laravel 5 possui um recurso que podemos chamar de Requests personalizadas, ou seja, criamosuma classe de Request e nela informamos os itens que devem ser validados.Utilizaremos o artisan para gerar automaticamente essa classe:

    1 php artisan make:request ProdutoRequest2 Request created successfully.

    O arquivo ProdutoRequest.php foi criado na pasta app/Http/Requests:

    1 // app/Http/Requests/ProdutoRequest.php23

  • Rumo ao primeiro CRUD 45

    29 ];30 }3132 }

    Perceba que temos dois mtodos nessa classe: authorize() e rules().O mtodo authorize() determina se temos autorizao de realizar essa request, logo, se ele retornartrue, quer dizer que ela pode ser executada. Entenda que voc poder colocar a regra que quiser parapermitir ou no a requisio de determinado usurio.J o mtodo rules(), responsvel por validar cada um dos dados enviados na request.O Laravel 5 j possui uma srie de validadores padro que podem ser encontrados em suaDocumentao Oficial.Nesse caso, faremos as seguintes alteraes em nossa classe ProdutoRequest:

    1

  • Rumo ao primeiro CRUD 46

    26 'nome' => 'required|min:5',27 'descricao' => 'required'28 ];29 }30 }

    Perceba que estamos agora retornando true no mtodo authorize(), e definimos que nomtodo rules() os atributos nome e descricao so obrigatrios e que o atributo nometambm precisa conter no mnimo 5 caracteres.

    Agora basta injetarmos essa classe como parmetro em nossa action store:

    1 // app/Http/Controllers/ProdutosController.php23

  • Rumo ao primeiro CRUD 47

    Dessa forma, toda requisio que chegar diretamente para a action store, ser validada pelo mtodorules() da request ProdutoRequest.Agora, se voc tentar criar um novo produto pelo formulrio e no informar nenhum valor, vocperceber que no ser redirecionado para a listagem de produtos e, aparentemente, nada acontece.S que na realidade, a nossa action store nem chegou a ser executada, uma vez que a requisio foiinterrompida quando o ProdutoRequest fez a validao que no retornou de forma positiva.Precisamos tambm informar ao usurio, quais informaes esto incorretas e/ou faltantes, nessecaso, trabalharemos com a varivel $errors, que armazena todos os erros de validao encontrados.Adicionaremos o seguinte trecho de cdigo no arquivo create.blade.php, verificando se h algumerro para se exibido, caso positivo, exibiremos os erros em uma lista:

    1 @if ($errors->any())2 3 @foreach($errors->all() as $error)4 {{ $error }}5 @endforeach6 7 @endif

    O resultado ficar da seguinte forma:

  • Rumo ao primeiro CRUD 48

    Erro de validao do formulrio

    O cdigo completo do arquivo create.blade.php ficou da seguinte forma:

    1 @extends('app')23 @section('content')4 5 Novo Produto67 @if ($errors->any())8 9 @foreach($errors->all() as $error)10 {{ $error }}11 @endforeach12 13 @endif1415 {!! Form::open(['url'=>'produtos/store']) !!}16

  • Rumo ao primeiro CRUD 49

    17 1819 20 {!! Form::label('nome', 'Nome:') !!}21 {!! Form::text('nome', null, ['class'=>'form-control']) !!}22 2324 2526 27 {!! Form::label('descricao', 'Descrio:') !!}28 {!! Form::textarea('descricao', null, ['class'=>'form-control']) !!}29 3031 32 {!! Form::submit('Criar Produto', ['class'=>'btn btn-primary']) !!}33 3435 {!! Form::close() !!}3637 38 @endsection

    Removendo registroTrabalhar com remoo de um registro no Laravel algo bem simples. Primeiramente, teremos quecriar uma action especfica para fazermos a remoo. Nesse caso, a chamaremos de destroy.

    1 // ProdutosController.php2 public function destroy($id)3 {4 Produto::find($id)->delete();56 return redirect('produtos');7 }89 Simples assim!1011 Agora, temos apenas que adicionar isso a nossas rotas:1213 ```php

  • Rumo ao primeiro CRUD 50

    14 // routes.php15 Route::get('produtos/{id}/destroy','ProdutosController@destroy');

    Quando voc acessar por exemplo: http:://localhost:8000/produtos/1/destroy, ele far, automatica-mente, a excluso do produto, cujo ID seja igual a 1.

    Editando registroO processo de edio de um registro muito similar ao de alterao, principalmente se formosanalisar a camada de viso.O primeiro passo para fazer a edio de um registro, entender o padro das URIs que vamos utilizar.

    1 // routes.php2 Route::get('produtos/{id}/edit','ProdutosController@edit');3 Route::put('produtos/{id}/update','ProdutosController@update');

    O padro da rota muito similar ao do destroy, porm, estamos encaminhando o request para aaction edit, para a mesma de trazer o formulrio de edio, e a action update para efetivar a alteraono banco de dados.

    Perceba que na rota de update, estamos utilizando o verbo http PUT ao invs de POST.Apesar de nossos browsers atualmente no suportarem tal recurso, o Laravel conseguecontonar esse ponto com uma soluo bem elegante.

    Vamos agora criar a action edit :

    1 public function edit($id)2 {3 $produto = Produto::find($id);45 return view('produtos.edit', compact('produto'));6 }

    Veja que um mtodo extremamente simples, que pega o produto atravs do mtodo find, e retornao produto encontrado para nossa view.Nesse ponto, temos apenas que criar nosso arquivo: edit.blade.php, dentro da pasta resources/vi-ews/produtos.

  • Rumo ao primeiro CRUD 51

    1 // resources/views/produtos/edit.blade.php23 @extends('app')45 @section('content')6 7 Editar Produto: {{$produto->name}}89 @if ($errors->any())10 11 @foreach($errors->all() as $error)12 {{ $error }}13 @endforeach14 15 @endif1617 {!! Form::open(['url'=>"produtos/$produto->id/update", 'method'=>'put'])\18 !!}1920 2122 23 {!! Form::label('nome', 'Nome:') !!}24 {!! Form::text('nome', $produto->nome, ['class'=>'form-control']) !!}25 2627 2829 30 {!! Form::label('descricao', 'Descrio:') !!}31 {!! Form::textarea('descricao', $produto->nome, ['class'=>'form-cont\32 rol']) !!}33 3435 36 {!! Form::submit('Salvar Produto', ['class'=>'btn btn-primary']) !!}37 3839 {!! Form::close() !!}4041 42 @endsection

  • Rumo ao primeiro CRUD 52

    Nesse caso, fizemos poucas alteraes em relao ao arquivo create.blade.php.

    1. Alteramos o ttulo da pgina para Editando Produto: Nome do produto2. A action do form para: produtos/update3. O Method do form de POST para PUT4. O valor padro dos campos dos formulrios. Ex:

    1 {!! Form::text('nome', $produto->nome, ['class'=>'form-control']) !!}

    Veja que nesse caso, ao invs de trazermos o valor padro do form como null, estamostrazendo com o valor do produto atual: $produto->nome.

    Formulrio de edio

    Est lembrado que mudamos o method do form de POST para PUT? Veja abaixo, o cdigofonte gerado pelo formulrio =)

  • Rumo ao primeiro CRUD 53

    Cdigo fonte do form de edio

    Perceba que o Laravel gerou automaticamente um campo hidden chamado _method com o valorde PUT. Apesar de nosso browser enviar a requisio via POST, o Laravel est aguardando umarequisio do tipo PUT, e nesse caso, ele far a leitura do valor enviado pelo _method para se adequar.Falta apenas implementarmos nosso mtodo de update para realizarmos a alterao no banco dedados.

    1 // ProdutosController.php23 public function update(ProdutoRequest $request, $id)4 {5 $produto = Produto::find($id)->update($request->all());67 return redirect('produtos');8 }

    Pronto, nosso update j est em funcionamento e nosso CRUD est completo.

    Ajustando rotasAt o momento, nosso arquivo de rotas est da seguinte forma:

  • Rumo ao primeiro CRUD 54

    1 Route::get('produtos','ProdutosController@index');23 Route::get('produtos/create','ProdutosController@create');45 Route::post('produtos/store','ProdutosController@store');67 Route::get('produtos/{id}/destroy','ProdutosController@destroy');89 Route::get('produtos/{id}/edit','ProdutosController@edit');1011 Route::put('produtos/{id}/update','ProdutosController@update');

    O grande ponto nesse caso, que podemos agrupar essas rotas por prefixo para facilitar amanuteno.Vejamos:

    1 Route::group(['prefix'=>'produtos'], function() {23 Route::get('','ProdutosController@index');45 Route::get('create','ProdutosController@create');67 Route::post('store','ProdutosController@store');89 Route::get('{id}/destroy','ProdutosController@destroy');1011 Route::get('{id}/edit','ProdutosController@edit');1213 Route::put('{id}/update','ProdutosController@update');1415 });

    Veja que separamos tudo por prefixo, ou seja, se mudarmos o prefixo, automaticamente todas asnossas rotas mudaro automaticamente.De qualquer modo, h duas coisas que, no mnimo, ainda precisam ser melhoradas:

    1. Nomear as rotas2. Validar nosso parmetro id

  • Rumo ao primeiro CRUD 55

    Nomeando nossas rotasAntes de comearmos a nomear as rotas, voc precisa entender quais so os infinitos benefcios queisso nos trs.Quando trabalhamos com rotas nomeadas, todos os links de nosso sistema, ao invs de chamar umaURL fixa (como estamos fazendo atualmente), podem chamar uma rota nomeada, e nesse caso, olink gerado dinamicamente de acordo com nossa rota; logo, se em algum momento resolvermosalterar nossas rotas, no precisaremos alterar absolutamente nada em nossas views.Vamos fazer isso!

    1 Route::group(['prefix'=>'produtos'], function() {23 Route::get('',['as'=>'produtos', 'uses'=>'ProdutosController@index']);45 Route::get('create',['as'=>'produtos.create', 'uses'=>'ProdutosController@cr\6 eate']);78 Route::post('store',['as'=>'produtos.store', 'uses'=>'ProdutosController@sto\9 re']);1011 Route::get('{id}/destroy',['as'=>'produtos.destroy', 'uses'=>'ProdutosContro\12 ller@destroy']);1314 Route::get('{id}/edit',['as'=>'produtos.edit', 'uses'=>'ProdutosController@e\15 dit']);1617 Route::put('{id}/update',['as'=>'produtos.update', 'uses'=>'ProdutosControll\18 er@update']);1920 });

    Se voc perceber, estamos utilizando uma key chamada as para nomearmos nossas rotas e a keyuses para definirmos para qual controller/action a mesma ser apontada.Feito isso, basta agora alterarmos todos os locais onde foramos uma URL por uma rota nomeada.Veja como ficou nosso ProdutosController:

  • Rumo ao primeiro CRUD 56

    1

  • Rumo ao primeiro CRUD 57

    43 }

    Em todos os locais onde redirecionamos o usurio para /produtos, alteramos para:redirect()->route(produtos);

    Tambm temos que alterar nossos forms: create.blade.php e edit.blade.php

    1 // create.blade.php2 {!! Form::open(['route'=>'produtos.store']) !!}34 // edit.blade.php5 {!! Form::open(['route'=>['produtos.update', $produto->id], 'method'=>'put']) !!}

    Agora temos total flexibilidade de linkar qualquer recurso interno do sistema, sem ter a preocupaode nossas rotas mudarem no futuro.

    Validando o parmetro ID de nossas rotasUm recurso que de extrema importncia no Laravel, a possibilidade de podermos validar osparmetros dinmicos de nossa rota, dessa forma, podemos ter mais segurana dos tipos e formatosde dados que esto entrando em nossas requisies.No nosso caso, utilizamos diversas vezes o parmetro ID para identificar qual o produto em questoque desejamos realizar alguma ao.Sabemos que nossos IDs so numricos, logo, podemos simplesmente adicionar tal validao emnossa rota:

    1 // routes.php23 Route::group(['prefix'=>'produtos', 'where'=>['id'=>'[0-9]+']], function() {45 Route::get('',['as'=>'produtos', 'uses'=>'ProdutosController@index']);67 Route::get('create',['as'=>'produtos.create', 'uses'=>'ProdutosController@cr\8 eate']);910 Route::post('store',['as'=>'produtos.store', 'uses'=>'ProdutosController@sto\11 re']);1213 Route::get('{id}/destroy',['as'=>'produtos.destroy', 'uses'=>'ProdutosContro\14 ller@destroy']);

  • Rumo ao primeiro CRUD 58

    1516 Route::get('{id}/edit',['as'=>'produtos.edit', 'uses'=>'ProdutosController@e\17 dit']);1819 Route::put('{id}/update',['as'=>'produtos.update', 'uses'=>'ProdutosControll\20 er@update']);2122 });

    Se voc tentar acessar qualquer URL que possua o parmetro ID sem passar um valor numrico,perceber que a rota no ser encontrada.Isso s acontece pelo fato de estarmos utilizando a key where, aplicando a regra de que apenasnumricos podem ser passados para o parmetro id ([0-9]+).Voc pode fazer infinitos tipos de validaes com suas rotas. Para saber mais, veja como isso podeser aplicado: Documentao oficial do Laravel - Routing.

    Linkando listagem de produtosPara finalizar esse captulo, faremos a linkagem desses recursos em nossa listagem de produtos noarquivo: index.blade.php:

    1. Link para criarmos novos produtos2. Link para editarmos um produto3. Link para removermos um produto

    1 // index.blade.php23 @extends('app')45 @section('content')6 7 Produtos89 Novo pr\10 oduto11 12 13

    http://laravel.com/docs/5.0/routing#route-parameters

  • Rumo ao primeiro CRUD 59

    14 15 16 ID17 Nome18 Descrio19 Ao20 21 22 2324 @foreach($produtos as $produto)25 26 {{ $produto->id }}27 {{ $produto->nome }}28 {{ $produto->descricao }}29 30 Editar32 Remover34 35 36 @endforeach3738 39 40 41 @endsection

    Todos os recursos foram linkados utilizando o helper route(), onde o primeiro parmetro o nomede nossa rota, e o segundo (opcional), um array com os valores que a rota precisa (como o $id porexemplo). Ex: {{ route(produtos.create) }}Tivemos nesse caso, como resultado final:

  • Rumo ao primeiro CRUD 60

    Listagem de produtos

  • Relacionando ModelsUm dos pontos que acredito que voc j deva estar curioso, como podemos fazer o relacionamentoentre Models, trabalhando com o Eloquent no Laravel.Acredite, trabalhar com relacionamentos muito simples no Laravel, e isso que vamos ver a partirde agora nesse captulo.

    Criando Model e MigrationNo momento, possumos nosso CRUD de produtos, todavia, gostaramos de poder adicionar umafuncionalidade simples em nosso sistema: Avaliar produtos.O objetivo que para cada produto cadastrado, possamos criar diversas avaliaes de clientes, logo,fica evidente que precisaremos de um outro participante que chamaremos de AvaliacaoProduto.Nesse caso, vamos criar nosso Model:

    1 php artisan make:model AvaliacaoProduto2 Model created successfully.3 Created Migration: 2015_05_06_180023_create_avaliacao_produtos_table

    Com nosso model criado, precisaremos editar nosso arquivo de migrao para que tenhamos o scriptde gerao de nossa tabela.

    1

  • Relacionando Models 62

    15 {16 Schema::create('avaliacao_produtos', function (Blueprint $table) {17 $table->increments('id');18 $table->integer('produto_id')->unsigned();19 $table->foreign('produto_id')->references('id')->on('produtos');20 $table->smallInteger('nota');21 $table->text('comentario');22 $table->timestamps();23 });24 }2526 /**27 * Reverse the migrations.28 *29 * @return void30 */31 public function down()32 {33 Schema::drop('avaliacao_produtos');34 }3536 }

    Perceba que nesse caso, alm de criar os campos nota e comentrio, tambm criamos um campochamado produto_id e o definimos como chave estrangeira, fazendo relao com o id de nossa tabelade produtos:

    1 $table->integer('produto_id');2 $table->foreign('produto_id')->references('id')->on('produtos');

    Agora, para que isso possa surtir efeito, temos que rodar nossas migraes novamente:

    1 php artisan migrate2 Migrated: 2015_05_06_180023_create_avaliacao_produtos_table

    Protinho! Nosso banco de dados agora possui uma nova tabela chamada avaliacao_produtos, quepossui uma chave estrangeira para nossa tabela de produtos.

    Criando relacionamentoAgora que j possumos nosso model AvaliacaoProduto, bem como sua tabela no banco de dados,precisaremos fazer nossos primeiros ajustes em nosso model para que ele possa se relacionar,naturalmente, com nosso model Produto.

  • Relacionando Models 63

    Para isso, inicialmente, adicionaremos o atributo $fillable em nosso model, para que possamostrabalhar com mass assignment e facilitar nosso processo de criao de novas avaliaes.

    1

  • Relacionando Models 64

    Se voc perceber, um Produto pode ter diversas Avaliaes, porm, uma avaliao pertenceunicamente a um produto.Nesse caso, definiremos essas relaes, exatamente da forma:

    1

  • Relacionando Models 65

    11 created_at: "2015-05-06 18:12:14",12 updated_at: "2015-05-06 18:12:14"13 }14 >>> $avaliacao->produto;15 => {16 id: "1",17 nome: "Livro de Laravel 5x",18 descricao: "Livro de Laravel 5",19 created_at: "2015-04-20 22:01:57",20 updated_at: "2015-04-28 20:42:34"21 }22 >>> $avaliacao->produto->nome;23 => "Livro de Laravel 5x"24 >>> $avaliacao->produto->descricao;25 => "Livro de Laravel 5"

    Veja que agora, basta executarmos a chamada ->produto em nosso model, que simplesmente teremosacesso ao Model referente a nossa chave estrangeira.

    Veja que estamos executando: $avaliacao->produto e no $avaliacao->produto().

    Por outro lado, seria muito interessante podermos fazer o inverso, ou seja, atravs de um produto,podermos pegar todas as avaliaes referenciadas a ele. Isso totalmente possvel, todavia, precisa-remos criar um outro mtodo para isso em nosso model Produto.

    1

  • Relacionando Models 66

    Nesse caso, criamos um mtodo chamado avaliacoes(), que tem o objetivo de retornar todas asavaliaes referentes a um determinado produto.Se voc analisar mais a fundo, ao invs de utilizarmos $this->belongsTo, como fizemos em nossomodel AvaliacaoProduto, trabalhamos com $this->hasMany, uma vez que o nosso produto podeter diversas avaliaes retornadas.Vamos ver como ficou:

    1 php artisan tinker2 Psy Shell v0.4.4 (PHP 5.6.4 cli) by Justin Hileman3 >>> use App\Produto;4 => false5 >>> $produto = Produto::find(1);6 => {7 id: "1",8 nome: "Livro de Laravel 5x",9 descricao: "Livro de Laravel 5",10 created_at: "2015-04-20 22:01:57",11 updated_at: "2015-04-28 20:42:34"12 }13 >>> $produto->avaliacoes;14 => [15 {16 id: "1",17 produto_id: "1",18 nota: "5",19 comentario: "primeiro comentario",20 created_at: "2015-05-06 18:12:14",21 updated_at: "2015-05-06 18:12:14"22 }23 ]

    O cdigo acima, nos deixa claro que ao chamarmos avaliacoes em nosso model Produto, automa-ticamente, ele far a busca por todas as avaliaes relacionadas e nos retornar uma Collection demodels de ProdutoAvaliacao que facilmente poder ser iterado com um foreach, por exemplo.

    Tabela Pivot (ManyToMany)Apesar dos relacionamentos anteriores serem extremamente utilizados, em diversos casos, pre-cisamos criar relacionamentos com uma tabela intermediria, pois nesse caso, o mesmo ser deMuitosParaMuitos (ManyToMany).

  • Relacionando Models 67

    Para que possamos exemplificar melhor esse tipo de relacionamento, criaremos um novo Modelchamado de Tag.Nesse caso, poderemos atribuir diversas tags aos nossos produtos, logo, uma tag pode estar ligada amais de um produto, da mesma forma que um produto poder estar ligado a mais de uma tag.

    1 php artisan make:model Tag2 Model created successfully.3 Created Migration: 2015_05_06_183634_create_tags_table

    1

  • Relacionando Models 68

    Agora que j possumos nosso arquivo de migrao para criarmos nossa tabela tags, basta,executarmos:

    1 php artisan migrate2 Migrated: 2015_05_06_183634_create_tags_table

    Prontinho!J possumos nosso Model Produto e Tag, porm, ainda est faltando nossa tabela para fazer ainterligao entre esses dois participantes, nesse caso, vamos criar uma nova migration:

    1 php artisan make:migration produtos_tags_table --create=produto_tag2 Created Migration: 2015_05_06_184107_produtos_tags_table

    O parmetro create, informa ao Laravel para criar o arquivo de migrao preparado parao processo de criao de uma tabela de banco de dados. Se voc pretende fazer a alteraode uma tabela, basta passar o parmetro: table=nome-da-tabela.

    1

  • Relacionando Models 69

    23 }2425 /**26 * Reverse the migrations.27 *28 * @return void29 */30 public function down()31 {32 Schema::drop('produtos_tags');33 }3435 }

    Nessa tabela, criamos duas chaves estrangeiras: produto_id e tag_id, dessa forma, ser possvel fazera ligao ManyToMany.

    1 php artisan migrate2 Migrated: 2015_05_06_184107_produtos_tags_table

    Da mesma forma que tivemos que implementar mtodos em nossos models para criarmos asrelaes entre Produto e AvaliacaoProduto, tambm, teremos que fazer essa implementao parao relacionamento entre Produto e Tag.

    1

  • Relacionando Models 70

    Veja que ao implementarmos o mtodo tag(), retornamos $this->belongsToMany ao invs desimplesmente $this->belongsTo. Isso j o suficiente para trabalharmos com o relacionamento demuitos-para-muitos. Vamos ao tinker:

    1 php artisan tinker2 Psy Shell v0.4.4 (PHP 5.6.4 cli) by Justin Hileman3 >>> use App\Tag;4 => false5 >>> use App\Produto;6 => false7 >>> $tag = new Tag;8 => {}9 >>> $tag->name = "Tag 1";10 => "Tag 1"11 >>> $tag->save()12 => true13 >>> $produto = Produto::find(1);14 => {15 id: "1",16 nome: "Livro de Laravel 5x",17 descricao: "Livro de Laravel 5",18 created_at: "2015-04-20 22:01:57",19 updated_at: "2015-04-28 20:42:34"20 }21 >>> $produto->tags()->attach($tag);22 => null23 >>> $produto->tags;24 => [25 {26 id: "1",27 name: "Tag 1",28 created_at: "2015-05-06 18:53:55",29 updated_at: "2015-05-06 18:53:55",30 pivot: {32 produto_id: "1",33 tag_id: "1"34 }35 }36 ]

    No exemplo acima, criamos uma tag chamada de Tag 1 e a atachamos ao nosso produto utilizando:$produto->tags()->attach($tag).

  • Relacionando Models 71

    Ao chamarmos $produto->tag, recebemos normalmente uma coleo de tags que est vinculada aonosso produto.Tenha mais detalhes sobre os relacionamentos / associaes de Models do Laravel, em sua Docu-mentao Oficial.

    http://laravel.com/docs/5.0/eloquent#relationships

  • Container de serviosServiosUm dos conceitos mais importantes que podemos aprender para trabalhar com qualquer frameworkmoderno o conceito de servios.Servios podem ser definidos como biblioteca(s), que normalmente so utilizadas em diversas partesdo nosso software.O grande ponto, que muitas dessas bibliotecas, podem possuir complexidades para sua configura-o inicial.Deixe-me lhe dar um exemplo:Vamos supor que temos um servio chamado de SampleService que para ser configurado, dependede um segundo servio chamado DependencyService.

    1 class MinhaClasse2 {34 public function __construct()5 {6 $config = [7 'config1' => 1,8 'config2' => 29 ];1011 $dependencyService = new DependencyService($config);1213 $sampleService = new SampleService($dependencyService);14 }15 }

    Agora, vamos imaginar que precisamos usar essa biblioteca em diversas partes de nosso software.Nesse ponto, acredito que voc j consiga perceber que todas as vezes que precisarmos dessabibliteca, teremos que realizar essas configuraes; e eventualmente, se essas configuraes foremalteradas, teremos que mudar em diversos lugares de nossa aplicao.Um outro grande problema de trabalharmos com tal abordagem, o acoplamento gerado na classeque utilizar essa bibliteca, nesse caso a classe MinhaClasse.

  • Container de servios 73

    Essa classe depende diretamente das classes DependencyService e SampleService, logo, futuramente,para que possamos reaproveit-la em outro software, etc teremos que, obrigatoriamente, levar essasdependncias tambm.Lembre-se, quanto mais desacopladas forem nossas classes, melhor!

    Dependency InjectionA melhor forma que podemos encontrar para termos classes mais desacopladas, trabalhar comum conceito muito simples de injeo de dependncia, mais conhecido como DI ou DependencyInjection.No caso acima, voc pode perceber que as nossas classes de servio esto sendo instanciadas dentroda classe MinhaClasse.Vamos mudar isso!

    1 // MinhaClasse.php2

  • Container de servios 74

    2728 $minhaClasse = new MinhaClasse($sampleService);

    Melhoramos nossa a classe MinhaClasse, uma vez que no estamos instanciando objetos dentro delamesma, todavia, ainda temos um probleminha.

    PROGRAME SEMPRE PARA UMA INTERFACE E NUNCA PARA UMA IMPLEMENTA-O

    O que a dica acima est dizendo, que mesmo injetanto nossa depedncia no construtor da classe,a mesma ainda depende, diretamente, de uma implementao concreta de SampleService.Isso no adequado, pois se algum dia quisermos fazer a classe MinhaClasse utilizar um outroservio similar ao SampleService, no ser possvel.A forma mais correta de sairmos desse impasse, trabalharmos com interfaces, fazendo com quenossa classe SampleService siga um determinado contrato para sua implementao.

    1

  • Container de servios 75

    26 }27 }2829 //bootstrap.php30

  • Container de servios 76

    Apenas lembrando que faremos uma implementao de um Repository de uma formaMUITO simples, apenas para que voc consiga entender o quo flexvel podemos deixarnossa aplicao.

    Nossa classe ProdutoRepository de forma completa se parece com isso:

    1 // app/Repositories/Eloquent/ProdutoRepository.php2

  • Container de servios 77

    37 public function delete($id)38 {39 return $this->model->find($id)->delete();40 }41 }

    Se voc perceber, o cdigo gera uma camada acima de nosso model, para que no precisemos expornossos models diretamente em nossas operaes com banco de dados em nossos controllers e outrasclasses de servios.O grande problema no cdigo acima, que uma vez que usamos uma implementao concreta deuma classe, todo nosso software ficar extremamente acoplado a essa implementao.Vamos imaginar se amanh, desejssemos trocar esse repository por um repository do DoctrineORM, por exemplo. Certamente teramos srios problemas, pois teramos que sair alterando emtodos os lugares que essa classe concreta est sendo chamada.Uma forma para deixarmos isso mais flexvel, fazer com que nossa classe implemente umainterface. Talvez no momento, isso no faa tanto sentido assim, mas tentarei ser o mais prticopossvel nesse caso.Vamos l:

    Criando uma Interface e um Abastract Repository

    O primeiro passo nessa nossa refatorao, ser definirmos uma Interface (contrato) para todos osrepositories que o implementarem.

    1 // app/Repositories/Contracts/RepositoryInterface.php23

  • Container de servios 78

    1 // app/Repositories/AbstractoRepository.php2

  • Container de servios 79

    1

  • Container de servios 80

    1

  • Container de servios 81

    17 {18 $produtos = $this->produtoRepository->getAll();1920 return view('produtos.index', ['produtos' => $produtos]);21 }22 }

    Perceba que no estamos fazendo em momento algum referncia para nossa classe ProdutoReposi-tory, mas sim para nossa Interface.A pergunta que no quer calar : Como o Laravel saber que dada a Interface ProdutoRepositoryIn-terface ele dever instanciar a classe concreta ProdutoRepository?Na realidade, ele no sabe, mas nesse caso, informaremos isso para ele em seu Container de Servios.Para isso vamos registrar isso no AppServiceProvider.

    1 // app/Providers/AppServiceProvider.php2

  • Container de servios 82

    28 public function register()29 {30 $this->app->bind(31 'Illuminate\Contracts\Auth\Registrar',32 'App\Services\Registrar'33 );3435 $this->app->bind(36 'App\Repositories\Contracts\ProdutoRepositoryInterface',37 'App\Repositories\Eloquent\ProdutoRepository'38 );39 }4041 }

    Nesse caso, estamos dizendo para o container que todas as vezes que a Interface: AppRepositori-esContractsProdutoRepositoryInterface for injetada como dependncia, automaticamente o Laraveldever retornar a classe concreta: AppRepositoriesEloquentProdutoRepository.Isso nos gerou uma flexibilidade fantstica, pois em se algum momento quisermos trocar nosso re-pository, basta mudarmos a chamada desse ServiceProvider e outra classe concreta que implementeessa mesma interface ser retornada.Por exemplo:

    1 $this->app->bind(2 'App\Repositories\Contracts\ProdutoRepositoryInterface',3 'App\Repositories\DoctrineORM\ProdutoRepository'4 );

    Perceba que nesse caso hipottico, se chamarmos a interface ProdutoRepositoryInterface, agorateremos o ProdutoRepository do DoctrineORM, por exemplo. Tambm no teremos que mudar umavirgula em nosso controller ou em outras classes.Continua

    ndice analticoIntroduoInstalaoInstalao via Laravel InstallerInstalao direta via composerExecutando Laravel pela primeira vez

    A estrutura do LaravelEstrutura de pastas e arquivosCiclo de vida de uma aplicao Laravel

    Configurando sua aplicao LaravelAlterando o Namespace de sua aplicaoConfigurando banco dadosConfigurando envio de emailsConfigurao do ambienteConcluindo

    Trabalhando com Rotas, Controllers e ViewsIntroduoVoltando s RotasControllersApontando para uma view

    ModelsIntroduoFalando sobre ModelsConfigurando um banco de dadosCriando nosso primeiro Model

    Rumo ao primeiro CRUDListando nossos ProdutosCriando novos produtosRemovendo registroEditando registroAjustando rotasLinkando listagem de produtos

    Relacionando ModelsCriando Model e MigrationCriando relacionamentoTabela Pivot (ManyToMany)

    Container de serviosServiosDependency InjectionContainers de servios