<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Áreadev]]></title><description><![CDATA[Áreadev]]></description><link>https://areadev.com.br</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1718561134047/j9voGmuuO.png</url><title>Áreadev</title><link>https://areadev.com.br</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 10 Sep 2026 00:33:27 GMT</lastBuildDate><atom:link href="https://areadev.com.br/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[MySQL com Docker Compose: guia completo (com correção do erro "Public Key Retrieval is not allowed")]]></title><description><![CDATA[https://youtu.be/tLK5nowvF8U

Se você chegou aqui pesquisando o erro "Public Key Retrieval is not allowed" ao tentar conectar no MySQL pelo DBeaver, pode pular direto para essa seção. Se está começand]]></description><link>https://areadev.com.br/mysql-com-docker-compose-guia-completo-com-corre-o-do-erro-public-key-retrieval-is-not-allowed</link><guid isPermaLink="true">https://areadev.com.br/mysql-com-docker-compose-guia-completo-com-corre-o-do-erro-public-key-retrieval-is-not-allowed</guid><category><![CDATA[Databases]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Fri, 14 Aug 2026 16:34:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/363251f2-1c33-4c18-9b03-7f50a8002a84.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a class="embed-card" href="https://youtu.be/tLK5nowvF8U">https://youtu.be/tLK5nowvF8U</a></p>

<p>Se você chegou aqui pesquisando o erro <strong>"Public Key Retrieval is not allowed"</strong> ao tentar conectar no MySQL pelo DBeaver, pode pular direto para <a href="#erro-public-key-retrieval-is-not-allowed">essa seção</a>. Se está começando do zero, siga o tutorial completo abaixo.</p>
<p>Neste guia você vai aprender a:</p>
<ul>
<li><p>Subir um container MySQL com Docker Compose, com dados persistidos na sua máquina</p>
</li>
<li><p>Evitar os dois erros mais comuns dessa configuração</p>
</li>
<li><p>Conectar no banco usando o DBeaver</p>
</li>
</ul>
<h2>Pré-requisitos</h2>
<ul>
<li><p>Docker instalado (<code>docker --version</code> para conferir)</p>
</li>
<li><p>Docker Compose instalado, de preferência a versão mais recente, integrada como plugin (<code>docker compose version</code>, sem hífen)</p>
</li>
<li><p>DBeaver instalado (ou qualquer outro cliente MySQL de sua preferência)</p>
</li>
</ul>
<div>
<div>💡</div>
<div><strong>Atenção à versão do Compose.</strong> Existem duas versões: a legada <code>docker-compose</code> (Python, standalone, descontinuada) e a atual <code>docker compose</code> (plugin oficial, sem hífen). Se <code>docker compose version</code> não funcionar, instale com <code>sudo apt install docker-compose-plugin</code>.</div>
</div>

<h2>Passo 1: criando o docker-compose.yml</h2>
<p>Crie uma pasta para o projeto e, dentro dela, um arquivo <code>docker-compose.yml</code>:</p>
<pre><code class="language-dockerfile">services:
  mysql_knex:
    container_name: mysql_knex
    hostname: mysql_knex
    image: mysql:8.0
    restart: always
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --innodb_force_recovery=0
    volumes:
      - ~/.MySQLDBData/mysqlonly/mysql_knex:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: senha
      MYSQL_DATABASE: base_de_dados
      MYSQL_USER: usuario
      MYSQL_PASSWORD: senha
      TZ: America/Sao_Paulo
</code></pre>
<p>Alguns pontos importantes desse arquivo:</p>
<p><strong>Fixe a versão da imagem.</strong> Usar <code>image: mysql</code> sem tag puxa sempre a versão mais recente disponível no Docker Hub. Isso é perigoso: uma versão nova pode remover flags que seu comando usa, quebrando a inicialização do container. Fixando <code>mysql:8.0</code>, você garante um comportamento previsível.</p>
<p><strong>O volume persiste os dados no seu host.</strong> A linha abaixo é o que garante que, se você derrubar o container, os dados não somem:</p>
<pre><code class="language-dockerfile">volumes:
  - ~/.MySQLDBData/mysqlonly/mysql_knex:/var/lib/mysql
</code></pre>
<p>Você pode confirmar seu caminho com <code>echo $HOME</code>. Se quiser evitar qualquer ambiguidade (por exemplo, ao rodar com <code>sudo</code>, onde <code>~</code> viraria <code>/root</code>), use o caminho absoluto direto no lugar do <code>~</code>.</p>
<h2>Passo 2: subindo o container</h2>
<p>Na pasta onde está o <code>docker-compose.yml</code>, rode:</p>
<pre><code class="language-dockerfile">docker compose up -d
</code></pre>
<p>Confirme que subiu com:</p>
<pre><code class="language-dockerfile">docker ps
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/60df260c-978e-4e25-ab9b-4ff71f6c0311.png" alt="" style="display:block;margin:0 auto" />

<p>O container <code>mysql_knex</code> deve aparecer com status <code>Up</code>. Se aparecer <code>Restarting</code>, o processo está travando em loop — siga para a próxima seção.</p>
<h2>Erro: unknown variable 'default-authentication-plugin'</h2>
<p>Se você usou algum tutorial mais antigo como referência, é comum ver a flag <code>--default-authentication-plugin=mysql_native_password</code> no <code>command:</code> do compose. Em versões recentes do MySQL, essa flag <strong>não existe mais</strong>, e o servidor recusa iniciar, entrando em crash loop.</p>
<p>Para confirmar que é esse o problema, veja os logs:</p>
<pre><code class="language-dockerfile">docker logs mysql_knex --tail 50
</code></pre>
<p>Se aparecer algo como:</p>
<pre><code class="language-dockerfile">[ERROR] [MY-000067] [Server] unknown variable 'default-authentication-plugin=mysql_native_password'.
[ERROR] [MY-010119] [Server] Aborting
</code></pre>
<p>A solução é remover essa flag do <code>command:</code> (como já está no <code>docker-compose.yml</code> deste tutorial) e deixar o MySQL 8 usar seu método de autenticação padrão, o <code>caching_sha2_password</code>.</p>
<p>Se o container já tentou subir e crashou antes de terminar a inicialização, é seguro resetar o volume, já que nenhum dado real chegou a ser gravado:</p>
<pre><code class="language-dockerfile">docker compose down
sudo rm -rf ~/.MySQLDBData/mysqlonly/mysql_knex
docker compose up -d
</code></pre>
<p>Depois disso, confira os logs de novo e espere aparecer a linha:</p>
<pre><code class="language-dockerfile">[Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.43' ...
</code></pre>
<p>Isso confirma que o MySQL subiu corretamente e está pronto para aceitar conexões.</p>
<h2>Passo 3: conectando pelo DBeaver</h2>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/3335355c-1ff0-42f9-843f-517a666e3543.png" alt="" style="display:block;margin:0 auto" />

<p>Abra o DBeaver e crie uma nova conexão MySQL, com os dados do seu <code>docker-compose.yml</code>:</p>
<ul>
<li><p><strong>Host:</strong> <code>localhost</code></p>
</li>
<li><p><strong>Port:</strong> <code>3306</code></p>
</li>
<li><p><strong>Database:</strong> o valor de <code>MYSQL_DATABASE</code></p>
</li>
<li><p><strong>Username:</strong> o valor de <code>MYSQL_USER</code></p>
</li>
<li><p><strong>Password:</strong> o valor de <code>MYSQL_PASSWORD</code></p>
</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/a43c9757-1ec2-4dde-9836-509b4a9d615a.png" alt="" style="display:block;margin:0 auto" />

<h2>Erro: Public Key Retrieval is not allowed</h2>
<p>Ao testar a conexão, é bem provável que apareça este erro:</p>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/2abd8d50-d963-40cd-9fd2-b9f453046c8d.png" alt="" style="display:block;margin:0 auto" />

<pre><code class="language-dockerfile">Public Key Retrieval is not allowed
</code></pre>
<p>Isso acontece porque o MySQL 8 usa o plugin de autenticação <code>caching_sha2_password</code>, que exige buscar uma chave pública RSA do servidor para autenticar com segurança. Por padrão, o driver JDBC bloqueia essa busca automática — é uma proteção contra ataques man-in-the-middle. Em ambiente de desenvolvimento local, é seguro habilitar manualmente.</p>
<p><strong>Como resolver no DBeaver:</strong></p>
<ol>
<li><p>Abra a conexão em <strong>Edit Connection</strong>.</p>
</li>
<li><p>Vá até a aba <strong>Driver properties</strong>.</p>
</li>
<li><p>Localize a propriedade <code>allowPublicKeyRetrieval</code> e defina como <code>true</code>. Se não existir na lista, adicione manualmente clicando no ícone <strong>+</strong>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/af6287c1-9623-4d2a-8a79-10e563cb7363.png" alt="" style="display:block;margin:0 auto" />
</li>
<li><p>Confirme também que <code>useSSL</code> está como <code>false</code>, já que não há certificado SSL configurado para produção nesse ambiente local.</p>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/77f33161-ba33-48dc-b1b9-cea0ba9aa1fd.png" alt="" style="display:block;margin:0 auto" />
</li>
<li><p>Clique em <strong>OK</strong> e teste a conexão novamente.</p>
</li>
</ol>
<p><strong>Alternativa mais rápida:</strong> editar direto a URL JDBC, na aba <strong>Main</strong>:</p>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/702b9905-aeae-47a5-8ab3-8898b4dfaf64.png" alt="" style="display:block;margin:0 auto" />

<pre><code class="language-plaintext">jdbc:mysql://localhost:3306/base_de_dados?allowPublicKeyRetrieval=true&amp;useSSL=false
</code></pre>
<div>
<div>💡</div>
<div>Essas duas flags são aceitáveis em desenvolvimento local. Em produção, o recomendado é configurar SSL de verdade em vez de desabilitar essas proteções.</div>
</div>

<h2>TCP/IP vs Unix socket: por que a porta importa</h2>
<p>Um detalhe que gera confusão: nos logs do MySQL você vai ver uma linha assim:</p>
<img src="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/c5473096-77e8-4399-ace5-0241cdf9fadc.png" alt="" style="display:block;margin:0 auto" />

<pre><code class="language-dockerfile">ready for connections. ... socket: '/var/run/mysqld/mysqld.sock' port: 3306
</code></pre>
<p>O MySQL aceita conexões de duas formas:</p>
<ul>
<li><p><strong>TCP/IP</strong>, via <code>localhost:3306</code> — é o que o DBeaver usa, mesmo estando na mesma máquina, porque ele roda fora do container e precisa atravessar a rede até o processo do MySQL.</p>
</li>
<li><p><strong>Unix socket</strong>, via o arquivo <code>mysqld.sock</code> — só acessível por processos dentro do mesmo container, como quando você entra nele diretamente com <code>docker exec -it mysql_knex mysql -u root -p</code>.</p>
</li>
</ul>
<p>Por isso, garantir que a porta <code>3306:3306</code> esteja mapeada corretamente no <code>docker-compose.yml</code> é essencial para qualquer cliente externo, como o DBeaver, conseguir se conectar.</p>
<h2>Bônus: comandos úteis para o dia a dia</h2>
<p><strong>Parar o container sem apagar dados:</strong></p>
<pre><code class="language-dockerfile">docker stop container_name
</code></pre>
<p><strong>Voltar a subir depois de parado:</strong></p>
<pre><code class="language-dockerfile">docker start container_name
</code></pre>
<p><strong>Ver logs em tempo real:</strong></p>
<pre><code class="language-dockerfile">docker logs -f mysql_knex
</code></pre>
<p><strong>Fazer backup do banco (dump):</strong></p>
<pre><code class="language-dockerfile">docker exec mysql_knex mysqldump -u root -p base_de_dados &gt; backup.sql
</code></pre>
<p><strong>Restaurar um backup:</strong></p>
<pre><code class="language-dockerfile">docker exec -i mysql_knex mysql -u root -p base_de_dados &lt; backup.sql
</code></pre>
<p><strong>Resetar tudo do zero (⚠️ apaga os dados permanentemente):</strong></p>
<pre><code class="language-dockerfile">docker compose down
sudo rm -rf ~/.MySQLDBData/mysqlonly/mysql_knex
docker compose up -d
</code></pre>
<h2>Conclusão</h2>
<p>Com esse setup você tem um MySQL rodando em container, com dados persistidos fora dele (então derrubar o container não te faz perder nada), e uma conexão funcional via DBeaver para gerenciar o banco visualmente. Os dois erros cobertos aqui — a flag de autenticação obsoleta e a recuperação de chave pública — são praticamente um rito de passagem para quem sobe MySQL 8 em Docker pela primeira vez, então se você travou neles, está em boa companhia.</p>
]]></content:encoded></item><item><title><![CDATA[Ngrok no Linux: Guia Completo de Instalação, Configuração e Uso]]></title><description><![CDATA[O que é o ngrok?

Ngrok permite expor um serviço local (por exemplo, um servidor web rodando no seu PC) para a internet por meio de um túnel seguro, sem precisar configurar redirecionamento de portas no roteador ou DNS complicada.

Requisitos prévios...]]></description><link>https://areadev.com.br/ngrok-no-linux-guia-completo-de-instalacao-configuracao-e-uso</link><guid isPermaLink="true">https://areadev.com.br/ngrok-no-linux-guia-completo-de-instalacao-configuracao-e-uso</guid><category><![CDATA[ngrok]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Developer]]></category><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Thu, 25 Sep 2025 03:43:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758771710005/29a9df42-1d98-4537-a058-6922022e25fe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-o-que-e-o-ngrok">O que é o ngrok?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758770970192/0866b487-7367-4236-bff6-6fed57449224.png" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://ngrok.com/docs/getting-started/">Ngrok</a> permite expor um serviço local (por exemplo, um servidor web rodando no seu PC) para a internet por meio de um túnel seguro, sem precisar configurar redirecionamento de portas no roteador ou DNS complicada.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768396275185/2e30ed02-fe68-4927-9872-89d1705c2d61.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-requisitos-previos">Requisitos prévios</h2>
<p>Antes de começar, você precisa:</p>
<ul>
<li><p>Ter uma conta no ngrok (gratuita ou paga).</p>
</li>
<li><p>Ter acesso ao terminal no Linux (shell).</p>
</li>
<li><p>Saber qual serviço/porta local você quer expor (por exemplo, servidor web em <a target="_blank" href="http://localhost:3000"><code>localhost:3000</code></a>).</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758768707926/61bd398b-0277-4129-8c30-9fc042789577.png" alt class="image--center mx-auto" /></p>
<p>Faça o login com uma conta do github ou google. Em seguida, siga esses passos!</p>
<p>Instale o ngrok via Apt com o seguinte comando:</p>
<pre><code class="lang-bash">curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
  | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc &gt;/dev/null \
  &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"deb https://ngrok-agent.s3.amazonaws.com bookworm main"</span> \
  | sudo tee /etc/apt/sources.list.d/ngrok.list \
  &amp;&amp; sudo apt update \
  &amp;&amp; sudo apt install ngrok
</code></pre>
<p>Execute o seguinte comando para adicionar seu authtoken ao arquivo de configuração padrão ngrok.yml.</p>
<pre><code class="lang-bash">ngrok config add-authtoken seu_token
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758768861480/03fe110e-623e-412c-8a28-dc8c5f08c749.png" alt class="image--center mx-auto" /></p>
<p>No arquivo será adicionado o seu token.</p>
<p>Agora veja a aplicação rodando no localhost sem o protocolo de segurança, muita das vezes utilizamos alguns serviços que exigem https.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769059891/b9ab1ed7-f212-41ab-935e-8ac9a11264f6.png" alt class="image--center mx-auto" /></p>
<p>Agora é que vem a mágica.</p>
<p>Faça o deploy do seu aplicativo, execute o seguinte na linha de comando:</p>
<pre><code class="lang-bash">ngrok http 8074
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769296234/f6776dfb-d9e2-49e5-9501-f64e9f589b8d.png" alt class="image--center mx-auto" /></p>
<p>Acesse seu domínio de desenvolvimento para ver seu aplicativo!</p>
<p><a target="_blank" href="https://unforsaken-extrusile-ainsley.ngrok-free.dev/">https://unforsaken-extrusile-ainsley.ngrok-free.dev</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769469455/041d2dfd-1a52-4650-9cb2-330ed5bdaff6.png" alt class="image--center mx-auto" /></p>
<p>Vai aparecer essa tela mas não se preocupe, clique no botão azul.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769516780/12fd2ae5-c807-4940-9202-46816acc8c3a.png" alt class="image--center mx-auto" /></p>
<p>Nossa aplicação está carregando, porém precisamos corrigir as urls para que o css e o javascript carreguem. Como a aplicação é um site em wordpress, basta inserir essas linhas no arquivo wp-config.php</p>
<pre><code class="lang-php">define(<span class="hljs-string">'WP_HOME'</span>,<span class="hljs-string">'https://unforsaken-extrusile-ainsley.ngrok-free.dev'</span>);
define(<span class="hljs-string">'WP_SITEURL'</span>,<span class="hljs-string">'https://unforsaken-extrusile-ainsley.ngrok-free.dev'</span>);
</code></pre>
<p>Agora nossa aplicação carregou perfeitamente.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769740408/c30c49fe-087a-47c0-8e1d-0fd337abce15.png" alt class="image--center mx-auto" /></p>
<p>Em nosso terminal, podemos visualizar o status de todas as requisições no HTTP Requests.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758769825321/889398e1-fb46-433f-b6b8-634073320748.png" alt class="image--center mx-auto" /></p>
<p>O ngrok cria uma <strong>interface de inspeção web</strong> local, onde você consegue ver todas as requisições que passam pelo túnel.</p>
<p>🔗 A URL padrão é:</p>
<pre><code class="lang-plaintext">http://127.0.0.1:4040
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758770038309/35ef7b59-0452-40f1-bb9c-56564562601b.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-o-que-voce-encontra-la">O que você encontra lá:</h3>
<ul>
<li><p>Lista de todas as requisições que chegaram ao túnel.</p>
</li>
<li><p>Método HTTP (GET, POST, PUT etc.).</p>
</li>
<li><p>Status de resposta (200, 404, 500…).</p>
</li>
<li><p>Corpo da requisição e da resposta.</p>
</li>
<li><p>Possibilidade de <strong>repetir requisições</strong> para testar seu servidor local.</p>
</li>
</ul>
<p>👉 Dica: se você precisar acessar essa interface de outro dispositivo ou servidor, dá para expor também o painel (<code>ngrok http 4040</code>), mas normalmente ele só fica disponível <strong>localmente</strong> por segurança.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768396292014/8ca0c870-d274-4e64-8914-2751d29d424d.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-resumo">📌 Resumo</h2>
<p>O <strong>ngrok</strong> é uma ferramenta poderosa para desenvolvedores que precisam expor serviços locais na internet de forma rápida e segura. Com ele, é possível compartilhar aplicações em desenvolvimento, realizar testes de integrações externas, validar webhooks e até mesmo acessar serviços internos sem configuração de rede complexa.</p>
<h2 id="heading-referencias">📚 Referências</h2>
<ul>
<li><p><a target="_blank" href="https://dashboard.ngrok.com/get-started/setup/linux?utm_source=chatgpt.com">Documentação oficial do ngrok — Setup Linux</a></p>
</li>
<li><p><a target="_blank" href="https://ngrok.com/docs/getting-started/?utm_source=chatgpt.com">ngrok Docs — Getting Started</a></p>
</li>
<li><p>ngrok Docs — Tunnels Configuration</p>
</li>
<li><p>ngrok Docs — API &amp; Inspector</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Ambientação Linux com Play with Docker]]></title><description><![CDATA[Se você quer aprender Linux, mas não quer instalar uma máquina virtual ou usar dual boot, uma ótima opção é utilizar o Play with Docker (PWD). Ele fornece um ambiente sandbox online, gratuito, onde podemos criar instâncias Linux para praticar comando...]]></description><link>https://areadev.com.br/ambientacao-linux-com-play-with-docker</link><guid isPermaLink="true">https://areadev.com.br/ambientacao-linux-com-play-with-docker</guid><category><![CDATA[Linux]]></category><category><![CDATA[linux for beginners]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Mon, 22 Sep 2025 21:31:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758629271127/d7c6c003-b974-442c-8ad6-979af6ad8c68.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Se você quer aprender Linux, mas não quer instalar uma máquina virtual ou usar dual boot, uma ótima opção é utilizar o <strong>Play with Docker (PWD)</strong>. Ele fornece um ambiente sandbox online, gratuito, onde podemos criar instâncias Linux para praticar comandos e testar conceitos.</p>
<p>Neste tutorial vamos:</p>
<ol>
<li><p>Criar uma instância no <strong>Play with Docker</strong></p>
</li>
<li><p>Conectar via <strong>SSH</strong> no nosso terminal local</p>
</li>
<li><p>Validar o acesso e começar os testes</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758576631483/2659f54e-82bc-411b-9d7e-17154330c70a.png" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://labs.play-with-docker.com/">https://labs.play-with-docker.com/</a></p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768397202976/4542d232-90bc-4d31-a49e-3fe1f06d8e8b.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-1-criando-uma-instancia-no-play-with-docker">1. Criando uma instância no Play with Docker</h2>
<ol>
<li><p>Acesse Play with Docker.</p>
</li>
<li><p>Clique em <strong>Login</strong> (você pode usar sua conta do Docker Hub).</p>
</li>
<li><p>Na tela inicial, clique em <strong>+ ADD NEW INSTANCE</strong>.</p>
</li>
</ol>
<p>Você verá algo assim:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758576142796/b6e121b2-9a05-4887-9d20-e05320766f83.png" alt class="image--center mx-auto" /></p>
<p>Cada instância criada terá:</p>
<ul>
<li><p>Um <strong>IP interno</strong> (ex: <code>192.168.0.14</code>)</p>
</li>
<li><p>Um <strong>comando SSH</strong> já pronto para conectar</p>
</li>
</ul>
<h2 id="heading-2-conectando-via-ssh">2. Conectando via SSH</h2>
<p>No painel da instância, você verá o comando SSH parecido com este:</p>
<pre><code class="lang-bash">ssh ip172-18-0-5-d38rg40l2o9000840akg@direct.labs.play-with-docker.com
</code></pre>
<p>Copie esse comando e cole no seu terminal local (Linux ou WSL).<br />Na primeira conexão, será exibido um aviso de autenticidade:</p>
<pre><code class="lang-bash">The authenticity of host <span class="hljs-string">'direct.labs.play-with-docker.com (...)'</span> can<span class="hljs-string">'t be established.
RSA key fingerprint is ...
Are you sure you want to continue connecting (yes/no/[fingerprint])?</span>
</code></pre>
<p>Digite <code>yes</code> e pressione <strong>Enter</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758576348209/17cb8153-682a-40fa-bbfc-af15838149f6.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-3-verificando-a-conexao">3. Verificando a conexão</h2>
<p>Após conectar, você terá acesso a um ambiente Linux remoto. A linha do terminal deve mudar para algo como:</p>
<pre><code class="lang-bash">[node1] (<span class="hljs-built_in">local</span>) root@192.168.0.14 ~ $
</code></pre>
<p>Pronto! Agora você pode começar a rodar comandos básicos de Linux, como:</p>
<pre><code class="lang-bash">ls
<span class="hljs-built_in">pwd</span>
whoami
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400094723/3ff31930-20da-464c-889f-2525fdfc766b.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-conclusao">🚀 Conclusão</h2>
<p>Com o <strong>Play with Docker</strong>, você tem um laboratório Linux rápido e prático para treinar os fundamentos sem precisar configurar máquinas virtuais.</p>
<p>👉 Dica: você pode salvar esse tutorial como referência para seus estudos ou até compartilhar com colegas que também estão começando no Linux.</p>
]]></content:encoded></item><item><title><![CDATA[Melhore sua Produtividade com Capturas de Tela no Pop!_OS usando Flameshot]]></title><description><![CDATA[Se você está buscando uma forma rápida e prática de tirar prints no Pop!_OS, o Flameshot é uma das melhores opções. Ele é leve, poderoso e altamente personalizável. Neste tutorial, você vai aprender como instalar e criar um atalho de teclado para usa...]]></description><link>https://areadev.com.br/melhore-sua-produtividade-com-capturas-de-tela-no-popos-usando-flameshot</link><guid isPermaLink="true">https://areadev.com.br/melhore-sua-produtividade-com-capturas-de-tela-no-popos-usando-flameshot</guid><category><![CDATA[PopOS]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Developer]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Thu, 24 Apr 2025 12:09:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745496424176/555d73f2-d9c0-4240-849a-e7a2bcda135e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Se você está buscando uma forma rápida e prática de tirar prints no Pop!_OS, o <a target="_blank" href="https://flameshot.org/">Flameshot</a> é uma das melhores opções. Ele é leve, poderoso e altamente personalizável. Neste tutorial, você vai aprender como instalar e criar um atalho de teclado para usar o Flameshot com um clique!</p>
<h2 id="heading-o-que-e-o-flameshothttpsflameshotorg">✅ O que é o <a target="_blank" href="https://flameshot.org/">Flameshot</a>?</h2>
<p>O Flameshot é uma ferramenta de captura de tela com editor embutido, que permite destacar, desenhar, adicionar setas, texto e muito mais. Perfeita para quem quer ir além do simples “Print Screen”.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400154561/02cb146d-0aba-4f6d-98ec-844e65b51fe9.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-instalando-o-flameshot-no-popos">📦 Instalando o Flameshot no Pop!_OS</h2>
<p>Pop!_OS é baseado no Ubuntu, então a instalação é bem tranquila via terminal:</p>
<ol>
<li><p><strong>Abra o terminal</strong></p>
</li>
<li><p>Digite o comando abaixo para atualizar os repositórios:</p>
<pre><code class="lang-bash"> sudo apt update
</code></pre>
</li>
<li><p>Agora instale o Flameshot:</p>
<pre><code class="lang-bash"> sudo apt install flameshot
</code></pre>
</li>
<li><p>Verifique se foi instalado corretamente:</p>
<pre><code class="lang-bash"> flameshot --version
</code></pre>
</li>
</ol>
<h2 id="heading-usando-o-flameshot">🔥 Usando o Flameshot</h2>
<p>Para fazer uma captura de tela a qualquer momento:</p>
<pre><code class="lang-bash">flameshot gui
</code></pre>
<p>Isso abrirá a interface interativa de captura. A partir daí, é só selecionar a área desejada e usar as ferramentas visuais.</p>
<h2 id="heading-criando-um-atalho-de-teclado-personalizado">🎯 Criando um Atalho de Teclado Personalizado</h2>
<p>Quer usar o Flameshot com a tecla <strong>Print Screen</strong>? Veja como:</p>
<ol>
<li><p>Vá até <strong>Settings (Configurações)</strong> no Pop!_OS</p>
</li>
<li><p>Clique em <strong>Keyboard</strong> no menu lateral</p>
</li>
<li><p>Desça até o final e clique em <strong>“View and Customize Shortcuts”</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745495114641/5ff20ac6-320f-46a0-b43c-f55d5e1ead9c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Role até <strong>Custom Shortcuts</strong> e clique no botão <strong>“+” (Add Shortcut)</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745495138859/a49ec4c2-7312-460d-9e48-9969fd8b033b.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745495217219/2d7eb3ea-884a-436c-88cd-78ca2bd28006.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Preencha os campos:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745495235422/fe8913f0-9276-4011-ad4e-d45457b91030.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><strong>Name:</strong> Flameshot</p>
</li>
<li><p><strong>Command:</strong> <code>flameshot gui</code></p>
</li>
<li><p><strong>Shortcut:</strong> clique em “Set Shortcut” e pressione a tecla <strong>Print Screen</strong></p>
</li>
</ul>
</li>
</ol>
<p>Se a tecla Print Screen já estiver em uso por outro atalho, você pode removê-lo ou usar uma combinação como <code>Ctrl + Shift + P</code>.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400173168/6112a2f2-2a49-420e-96ed-edf85f27f0bb.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-pronto-para-capturar">🚀 Pronto para capturar!</h2>
<p>Com o Flameshot instalado e um atalho configurado, suas capturas de tela no Pop!_OS ficam muito mais rápidas e organizadas. Ideal para tutoriais, documentação ou qualquer tarefa que envolva imagens da tela com anotações.</p>
<p><a target="_blank" href="https://flameshot.org/">flameshot</a><br /><a target="_blank" href="https://flameshot.org/docs/">documentação</a></p>
]]></content:encoded></item><item><title><![CDATA[Como Resolver o Erro "git@github.com: Permission denied (publickey)" ao Clonar um Repositório GitHub]]></title><description><![CDATA[Se você está tentando clonar um repositório do GitHub e se deparou com o seguinte erro:
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the reposito...]]></description><link>https://areadev.com.br/como-resolver-erro-permission-denied-github</link><guid isPermaLink="true">https://areadev.com.br/como-resolver-erro-permission-denied-github</guid><category><![CDATA[GitHub]]></category><category><![CDATA[ssh-keys]]></category><category><![CDATA[terminal]]></category><category><![CDATA[Linux]]></category><category><![CDATA[PopOS]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Wed, 26 Feb 2025 22:23:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740609030117/30abe157-9172-4b4d-a324-f8df5462da6d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Se você está tentando clonar um repositório do GitHub e se deparou com o seguinte erro:</p>
<pre><code class="lang-bash">git@github.com: Permission denied (publickey).
fatal: Could not <span class="hljs-built_in">read</span> from remote repository.

Please make sure you have the correct access rights
and the repository exists.
</code></pre>
<p>Não se preocupe! Esse erro ocorre porque o GitHub não conseguiu autenticar sua chave SSH. Neste guia, vamos mostrar um passo a passo para solucionar esse problema e garantir que você consiga acessar seus repositórios sem dificuldades.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400246106/27bda5f0-1531-4807-b983-f855ed586cee.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-o-que-causa-esse-erro">O Que Causa Esse Erro?</h2>
<p>O erro "Permission denied (publickey)" normalmente acontece por um dos seguintes motivos:</p>
<ol>
<li><p><strong>Você não tem uma chave SSH configurada no seu computador.</strong></p>
</li>
<li><p><strong>Sua chave SSH não está adicionada ao GitHub.</strong></p>
</li>
<li><p><strong>O agente SSH não está em execução ou sua chave não está carregada.</strong></p>
</li>
<li><p><strong>Você está tentando clonar usando SSH, mas sua conta só permite acessos via HTTPS.</strong></p>
</li>
</ol>
<p>Agora, vamos resolver o problema!</p>
<h2 id="heading-passo-1-verificar-se-voce-tem-uma-chave-ssh-configurada">Passo 1: Verificar Se Você Tem Uma Chave SSH Configurada</h2>
<p>Primeiro, verifique se já existe uma chave SSH no seu sistema. Abra o terminal e digite:</p>
<pre><code class="lang-bash">ls -al ~/.ssh
</code></pre>
<p>Se o comando listar arquivos como <code>id_rsa</code> e <code>id_rsa.pub</code> ou <code>id_ed25519</code> e <code>id_ed25519.pub</code>, significa que você já tem uma chave SSH configurada.</p>
<p>Se <strong>não</strong> houver chaves, você precisa gerar uma nova.</p>
<h2 id="heading-passo-2-criar-uma-nova-chave-ssh-se-necessario">Passo 2: Criar Uma Nova Chave SSH (Se Necessário)</h2>
<p>Se você precisa criar uma nova chave SSH, utilize este comando:</p>
<pre><code class="lang-bash">ssh-keygen -t ed25519 -C <span class="hljs-string">"seu-email@example.com"</span>
</code></pre>
<p>Caso seu sistema não suporte Ed25519, use RSA:</p>
<pre><code class="lang-bash">ssh-keygen -t rsa -b 4096 -C <span class="hljs-string">"seu-email@example.com"</span>
</code></pre>
<p>Depois de rodar esse comando, pressione <code>Enter</code> para confirmar o local padrão da chave e, se quiser, defina uma senha.</p>
<h2 id="heading-passo-3-adicionar-a-chave-ssh-ao-github">Passo 3: Adicionar a Chave SSH ao GitHub</h2>
<p>Agora, você precisa adicionar sua chave SSH ao GitHub:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740608778005/a47720c6-11e5-4ea7-88de-2a94cc217200.png" alt class="image--center mx-auto" /></p>
<ol>
<li><p>Pegue a chave pública com este comando:</p>
<pre><code class="lang-bash"> cat ~/.ssh/id_ed25519.pub  <span class="hljs-comment"># Ou ~/.ssh/id_rsa.pub se for RSA</span>
</code></pre>
</li>
<li><p>Copie o conteúdo exibido.</p>
</li>
<li><p>Acesse <a target="_blank" href="https://github.com/settings/keys">GitHub → Configurações → SSH and GPG keys</a>.</p>
</li>
<li><p>Clique em <strong>New SSH Key</strong>.</p>
</li>
<li><p>Cole a chave pública e salve.</p>
</li>
</ol>
<h2 id="heading-passo-4-testar-a-conexao-ssh-com-o-github">Passo 4: Testar a Conexão SSH com o GitHub</h2>
<p>Para verificar se a autenticação SSH está funcionando, rode:</p>
<pre><code class="lang-bash">ssh -T git@github.com
</code></pre>
<p>Se tudo estiver correto, você verá uma mensagem como esta:</p>
<pre><code class="lang-bash">Hi &lt;username&gt;! You<span class="hljs-string">'ve successfully authenticated, but GitHub does not provide shell access.</span>
</code></pre>
<h2 id="heading-passo-5-certificar-se-de-que-o-agente-ssh-esta-rodando">Passo 5: Certificar-se de que o Agente SSH Está Rodando</h2>
<p>Se o erro persistir, pode ser que sua chave SSH não esteja carregada. Para resolver isso, execute:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-subst">$(ssh-agent -s)</span>"</span>
ssh-add ~/.ssh/id_ed25519  <span class="hljs-comment"># Ou ~/.ssh/id_rsa</span>
</code></pre>
<h2 id="heading-passo-6-alternativa-usar-https-ao-inves-de-ssh">Passo 6: Alternativa - Usar HTTPS ao Invés de SSH</h2>
<p>Se você não quiser usar SSH, pode clonar o repositório via HTTPS:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/usuario/repositorio.git
</code></pre>
<p>Isso não exige chaves SSH, mas você precisará inserir suas credenciais toda vez que fizer push ou pull.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400257859/e8e60dac-dca0-494a-be10-3ff37d16b96a.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-conclusao">Conclusão</h2>
<p>Seguindo esses passos, você deve conseguir corrigir o erro "Permission denied (publickey)" e acessar seus repositórios no GitHub sem problemas. Se o erro persistir, verifique se a chave correta está sendo usada e se sua conta GitHub está configurada corretamente.</p>
<p>Agora é só codar e versionar seus projetos sem dores de cabeça! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Como configurar e utilizar o Tailwindcss]]></title><description><![CDATA[📦 Requisitos

Ambiente com suporte a Node.js e npm (como o StackBlitz ou sua máquina local)

Um editor de código (VS Code, StackBlitz, etc.)




1. Inicializar projeto
Se estiver começando do zero (localmente):
mkdir meu-projeto-tailwind
cd meu-proj...]]></description><link>https://areadev.com.br/como-configurar-e-utilizar-o-tailwindcss</link><guid isPermaLink="true">https://areadev.com.br/como-configurar-e-utilizar-o-tailwindcss</guid><category><![CDATA[CSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Wed, 18 Dec 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758766347521/ddfcd356-1dc8-47a9-ac55-69c900555a69.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-requisitos">📦 Requisitos</h3>
<ul>
<li><p>Ambiente com suporte a Node.js e npm (como o StackBlitz ou sua máquina local)</p>
</li>
<li><p>Um editor de código (VS Code, StackBlitz, etc.)</p>
</li>
</ul>
<hr />
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400323241/6c283d33-8608-45e4-ae0a-fbdc2485acb1.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-1-inicializar-projeto">1. Inicializar projeto</h2>
<p>Se estiver começando do zero (localmente):</p>
<pre><code class="lang-plaintext">mkdir meu-projeto-tailwind
cd meu-projeto-tailwind
npm init -y
</code></pre>
<p>Isso cria o <code>package.json</code> e estrutura mínima.</p>
<pre><code class="lang-plaintext">/meu-projeto-tailwind
│
├── index.html
├── tailwind.css
├── styles.css
├── tailwind.config.js
└── package.json (criado automaticamente ao instalar Tailwind)
</code></pre>
<p>(No <a target="_blank" href="https://stackblitz.com/">StackBlitz</a> talvez já haja um ambiente inicial, então você pode pular esse passo se já existir <code>package.json</code>.)</p>
<h2 id="heading-passo-2-instalar-tailwind-css-e-dependencias">Passo 2: Instalar Tailwind CSS e dependências</h2>
<p>Execute:</p>
<pre><code class="lang-plaintext">npm install -D tailwindcss@3.4.17 postcss autoprefixer
npx tailwindcss init -p
</code></pre>
<p>Explicações:</p>
<ul>
<li><p><code>tailwindcss@3.4.17</code> força instalar essa versão (ou algo próximo)</p>
</li>
<li><p><code>postcss</code> e <code>autoprefixer</code> são usados para processar CSS e adicionar prefixos necessários</p>
</li>
<li><p><code>npx tailwindcss init -p</code> cria dois arquivos:</p>
<ul>
<li><p><code>tailwind.config.js</code></p>
</li>
<li><p><code>postcss.config.js</code></p>
</li>
</ul>
</li>
</ul>
<p>Após isso, você terá:</p>
<pre><code class="lang-plaintext">
/meu-projeto-tailwind
│
├── node_modules/
├── index.html
├── tailwind.css
├── styles.css
├── postcss.config.js
├── tailwind.config.js
└── package.json (criado automaticamente ao instalar Tailwind)
</code></pre>
<p>No <code>tailwind.config.js</code>, o conteúdo padrão será algo como:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {},
  },
  <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
<p>No <code>postcss.config.js</code>, geralmente:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">plugins</span>: {
    <span class="hljs-attr">tailwindcss</span>: {},
    <span class="hljs-attr">autoprefixer</span>: {},
  }
}
</code></pre>
<h2 id="heading-passo-3-configurar-os-caminhos-de-content-template-paths">Passo 3: Configurar os caminhos de “content” (template paths)</h2>
<p>O Tailwind precisa saber onde procurar suas classes (em arquivos HTML, JS, etc) para gerar CSS apenas para as classes usadas. Isso ajuda a <strong>tree-shake</strong> (remover classes não utilizadas) e reduzir o tamanho final do CSS.</p>
<p>No seu <code>tailwind.config.js</code>, edite a propriedade <strong>content</strong>. Por exemplo, para um projeto simples:</p>
<pre><code class="lang-javascript">
<span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">"./*.html"</span>,
    <span class="hljs-string">"./src/**/*.{html,js}"</span>,  <span class="hljs-comment">// se você tiver pasta `src`</span>
  ],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {},
  },
  <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
<p>Se seus arquivos HTML, JS, componentes estiverem em outras pastas, inclua seus padrões.</p>
<p>Esse passo é fundamental para que o Tailwind “veja” as classes que você usa e inclua os estilos gerados.</p>
<h2 id="heading-passo-4-criar-arquivo-css-de-entrada-input-css">Passo 4: Criar arquivo CSS de entrada (input CSS)</h2>
<p>Crie um arquivo CSS (por exemplo <code>src/tailwind.css</code> ou <code>src/css/tailwind.css</code>) com o seguinte conteúdo:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;

<span class="hljs-comment">/* Aqui você pode adicionar suas próprias regras CSS ou usar @layer / @apply */</span>
</code></pre>
<p>Esse arquivo será o ponto de entrada do Tailwind para gerar o CSS final.</p>
<h2 id="heading-passo-5-compilar-o-css">Passo 5: Compilar o CSS</h2>
<p>Agora você deve “processar” o <code>tailwind.css</code> junto com as configurações para gerar um CSS final (ex: <code>dist/output.css</code>). Há várias formas de fazer isso:</p>
<h4 id="heading-usando-tailwind-cli">Usando Tailwind CLI</h4>
<p>Esse é o método mais simples:</p>
<pre><code class="lang-bash">
npx tailwindcss -i ./src/tailwind.css -o ./dist/output.css --watch
</code></pre>
<p>Explicação:</p>
<ul>
<li><p><code>-i</code>: arquivo de entrada (input)</p>
</li>
<li><p><code>-o</code>: arquivo de saída (output)</p>
</li>
<li><p><code>--watch</code>: fica observando alterações e recompila automaticamente</p>
</li>
</ul>
<p>Depois disso, o arquivo <code>dist/output.css</code> será gerado e atualizado conforme você altera seus arquivos HTML ou CSS.</p>
<p>Esse método é também o indicado na documentação oficial.</p>
<h4 id="heading-usando-postcss-bundlers-webpack-vite-etc">Usando PostCSS / bundlers (webpack, Vite, etc)</h4>
<p>Se você tiver um pipeline mais avançado:</p>
<ul>
<li><p>Seu bundler (webpack, Vite, Rollup...) já executa PostCSS como parte da cadeia de build.</p>
</li>
<li><p>No <code>postcss.config.js</code>, você já incluiu <code>tailwindcss</code> e <code>autoprefixer</code>.</p>
</li>
<li><p>Você importa ou referencia no build esse <code>input.css</code> (ou outro arquivo) para ser processado.</p>
</li>
</ul>
<p>Por exemplo, no Vite, você coloca:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// vite.config.js (exemplo)</span>
<span class="hljs-keyword">import</span> { defineConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"vite"</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> defineConfig({
  <span class="hljs-attr">css</span>: {
    <span class="hljs-attr">postcss</span>: <span class="hljs-literal">true</span>
  }
})
</code></pre>
<p>E no seu código (por exemplo <code>main.js</code>):</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">"./tailwind.css"</span>
</code></pre>
<p>E o bundler cuidará de compilar com PostCSS e gerar CSS final.</p>
<p>A documentação do Tailwind tem guias específicos para frameworks, como Vite.</p>
<h2 id="heading-passo-6-incluir-css-compilado-no-html">Passo 6: Incluir CSS compilado no HTML</h2>
<p>No seu arquivo HTML (ex: <code>index.html</code>), no <code>&lt;head&gt;</code>, incluia:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"./dist/output.css"</span>&gt;</span>
</code></pre>
<p>Ou o caminho correto para seu CSS de saída.</p>
<p>Exemplo mínimo:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"pt-br"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"dist/output.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Projeto Tailwind<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold underline"</span>&gt;</span>Olá, Tailwind!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Se o CSS compilado estiver sendo servido por outra rota ou servidor, ajuste a URL de acordo.</p>
<h2 id="heading-passo-7-usar-classes-utilitarias-no-html">Passo 7: Usar classes utilitárias no HTML</h2>
<p>Agora é a parte divertida: você já pode usar as classes do Tailwind no seu HTML.</p>
<p>Alguns exemplos:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"</span>&gt;</span>
  Clicar
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-md mx-auto mt-10"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-700 leading-relaxed"</span>&gt;</span>
    Exemplo com Tailwind CSS.
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Você pode combinar classes utilitárias para layout, cores, espaçamento, tipografia, responsividade etc.</p>
<h2 id="heading-passo-8-customizacoes-e-refinamentos-opcional">Passo 8: Customizações e refinamentos (opcional)</h2>
<p>Depois que tudo estiver funcionando, você pode:</p>
<ul>
<li><p>Estender tema no <code>tailwind.config.js</code> (cores, fontes, espaçamentos, etc)</p>
</li>
<li><p>Usar <code>@apply</code> para criar classes personalizadas</p>
</li>
<li><p>Usar <code>@layer components</code> ou <code>@layer utilities</code></p>
</li>
<li><p>Instalar plugins do Tailwind (por exemplo tipografia, forms)</p>
</li>
<li><p>Ativar modo “dark”, variantes e outras configurações</p>
</li>
<li><p>Certificar-se de que o “purge” / remoção de CSS não usado esteja funcionando bem (configuração <code>content</code>)</p>
</li>
</ul>
<hr />
<p><strong>Tailwind CSS</strong> é um framework utilitário para criação rápida de interfaces com classes pré-definidas. A versão <strong>3.4.17</strong> inclui recursos modernos como JIT (Just-In-Time), dark mode, variantes estendidas, e mais.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400344060/edc88515-c057-4f06-9a1f-d01d96afb46c.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-referencias">📚 Referências</h2>
<ul>
<li><p><a target="_blank" href="https://v3.tailwindcss.com/docs/installation?utm_source=chatgpt.com">📘 Documentação oficial do Tailwind CSS v3</a></p>
</li>
<li><p><a target="_blank" href="https://v3.tailwindcss.com/docs/installation/using-postcss">📘 Guia de instalação via CLI</a></p>
</li>
<li><p><a target="_blank" href="https://v3.tailwindcss.com/docs/content-configuration">📘 Conteúdo sobre paths no Tailwind</a></p>
</li>
<li><p><a target="_blank" href="https://stackblitz.com/edit/stackblitz-starters-jxvamnph?description=HTML/CSS/JS%20Starter&amp;file=index.html,tailwind.css,styles.css,tailwind.config.js,postcss.config.js&amp;terminalHeight=10&amp;title=Static%20Starter">📘 Tailwind CSS no StackBlitz (exemplo usado pelo usuário)</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[O que é Zsh e para que serve?]]></title><description><![CDATA[Zsh, ou Z shell, é um poderoso interpretador de comandos e um substituto avançado para o shell padrão do Unix, o Bash. Ele é amplamente utilizado por desenvolvedores e usuários que buscam mais recursos e flexibilidade em comparação com outros shells....]]></description><link>https://areadev.com.br/o-que-e-zsh-e-para-que-serve</link><guid isPermaLink="true">https://areadev.com.br/o-que-e-zsh-e-para-que-serve</guid><category><![CDATA[terminal]]></category><category><![CDATA[Linux]]></category><category><![CDATA[shell]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Mon, 22 Jul 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729361365267/0cb87d4f-1703-45e5-890d-ccaa09c71fb4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Zsh, ou <strong>Z shell</strong>, é um poderoso interpretador de comandos e um substituto avançado para o shell padrão do Unix, o Bash. Ele é amplamente utilizado por desenvolvedores e usuários que buscam mais recursos e flexibilidade em comparação com outros shells.</p>
<p>O Zsh é projetado para ser compatível com o Bash, mas oferece funcionalidades adicionais, como autocompletar avançado, sugestões de comandos, e uma personalização extensiva por meio de temas e plugins.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400440670/3fa3d1e9-14d6-47e8-a12b-77088e6bbfa7.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-principais-caracteristicas-do-zsh">Principais Características do Zsh</h3>
<ol>
<li><p><strong>Autocompletar Inteligente:</strong> O Zsh possui um autocompletar avançado que sugere opções e argumentos de comandos, facilitando a execução rápida e precisa de comandos.</p>
</li>
<li><p><strong>Correção de Erros de Digitação:</strong> Ele pode corrigir automaticamente comandos digitados incorretamente ou sugerir correções para os erros, tornando a experiência de uso mais agradável.</p>
</li>
<li><p><strong>Histórico de Comandos Aprimorado:</strong> O histórico de comandos do Zsh é mais robusto, com recursos de pesquisa interativa e reutilização de comandos anteriores.</p>
</li>
<li><p><strong>Suporte a Plugins e Temas:</strong> Com frameworks como Oh My Zsh, o Zsh oferece suporte fácil para plugins e temas, que podem melhorar a funcionalidade e a aparência do terminal.</p>
</li>
<li><p><strong>Globbing Avançado:</strong> O Zsh permite correspondência avançada de padrões de nomes de arquivos, o que é útil para buscar e manipular arquivos de forma mais complexa.</p>
</li>
<li><p><strong>Aliases e Funções Personalizadas:</strong> O Zsh facilita a criação de aliases (atalhos para comandos) e funções personalizadas, melhorando a produtividade e a eficiência.</p>
</li>
</ol>
<h3 id="heading-para-que-serve-o-zsh">Para que Serve o Zsh?</h3>
<p>O Zsh é usado principalmente para melhorar a experiência de uso do terminal. Ele oferece recursos que facilitam a execução de tarefas repetitivas, o uso de atalhos, e a personalização do ambiente de trabalho. Por isso, é uma escolha popular entre desenvolvedores, administradores de sistemas e entusiastas do Linux que desejam um terminal mais eficiente e produtivo.</p>
<h3 id="heading-passo-a-passo-para-instalacao-do-zsh-no-popos">Passo a Passo para Instalação do Zsh no Pop!_OS</h3>
<ol>
<li><p><strong>Atualizar o sistema</strong></p>
<p> Antes de instalar o Zsh, é recomendado atualizar o sistema para garantir que todos os pacotes estejam nas versões mais recentes:</p>
<pre><code class="lang-bash"> sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
</li>
<li><p><strong>Instalar o Zsh</strong></p>
<p> Para instalar o Zsh, use o comando abaixo:</p>
<pre><code class="lang-bash"> sudo apt install zsh -y
</code></pre>
<p> Isso instalará o Zsh a partir dos repositórios padrão do Pop!_OS.</p>
</li>
<li><p><strong>Verificar a instalação</strong></p>
<p> Para garantir que o Zsh foi instalado corretamente, execute o comando:</p>
<pre><code class="lang-bash"> zsh --version
</code></pre>
<p> Você verá a versão do Zsh instalada, o que indica que a instalação foi bem-sucedida.</p>
</li>
<li><p><strong>Configurar o Zsh como o shell padrão</strong></p>
<p> Para definir o Zsh como o shell padrão do usuário, use o comando:</p>
<pre><code class="lang-bash"> chsh -s $(<span class="hljs-built_in">which</span> zsh)
</code></pre>
<p> Isso configurará o Zsh como o shell principal. É necessário fazer logout e login novamente para que a mudança tenha efeito.</p>
</li>
<li><p>Instalar o Oh My Zsh (opcional, mas recomendado)</p>
<p> Oh My Zsh é um framework de código aberto para gerenciar a configuração do Zsh. Ele facilita a personalização com temas e plugins. Para instalar o Oh My Zsh, execute:</p>
<pre><code class="lang-bash"> sh -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)</span>"</span>
</code></pre>
<p> Isso instalará o Oh My Zsh e criará automaticamente um arquivo de configuração <code>.zshrc</code> no diretório home.</p>
</li>
<li><p><strong>Personalizar o Zsh</strong></p>
<pre><code class="lang-bash"> ZSH_THEME=<span class="hljs-string">"robbyrussell"</span>
</code></pre>
<p> Você pode substituir <code>"robbyrussell"</code> pelo nome de outro tema disponível.</p>
</li>
<li><p><strong>Adicionar Plugins</strong><br /> O Zsh suporta plugins que melhoram a funcionalidade do terminal. Por exemplo, para ativar o plugin <code>git</code>, edite o arquivo <code>~/.zshrc</code> e adicione <code>git</code> à lista de plugins:</p>
<pre><code class="lang-bash"> plugins=(git)
</code></pre>
<p> Após modificar o arquivo, atualize o Zsh com o comando:</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">source</span> ~/.zshrc
</code></pre>
</li>
</ol>
<p><a target="_blank" href="https://github.com/ohmyzsh/ohmyzsh/wiki/Themes">Themes to ohmyzsh</a></p>
<p><a target="_blank" href="https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes">External themes to ohmyszh</a></p>
<p><a target="_blank" href="https://spaceship-prompt.sh/">Spaceship Prompt</a></p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400466587/860e9289-13f5-48ba-b528-caf0e8b45302.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>O Zsh é uma excelente opção para quem busca um shell mais avançado e customizável. Com suas funcionalidades aprimoradas, ele pode tornar o uso do terminal mais eficiente e produtivo. Além disso, a instalação e configuração são simples, especialmente com o uso de frameworks como o Oh My Zsh.</p>
]]></content:encoded></item><item><title><![CDATA[Tipos de Teste: Fundamentos que Todo QA Precisa Dominar]]></title><description><![CDATA[Garantir a qualidade de um produto digital vai muito além de simplesmente “clicar na tela”. O papel do QA (Quality Assurance) é estratégico e essencial para o sucesso de qualquer projeto de software. Entender os diferentes tipos de teste e quando apl...]]></description><link>https://areadev.com.br/tipos-de-teste-fundamentos-que-todo-qa-precisa-dominar</link><guid isPermaLink="true">https://areadev.com.br/tipos-de-teste-fundamentos-que-todo-qa-precisa-dominar</guid><category><![CDATA[QA]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Tue, 25 Jun 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762965172654/ca0e26b1-a142-4213-b0fe-24e1954ce6d3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Garantir a qualidade de um produto digital vai muito além de simplesmente “clicar na tela”. O papel do QA (Quality Assurance) é estratégico e essencial para o sucesso de qualquer projeto de software. Entender <strong>os diferentes tipos de teste</strong> e <strong>quando aplicá-los</strong> é o que diferencia um bom profissional de qualidade de um testador operacional.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400923316/f8ded932-9277-4c49-9f1b-20d5ca0c5803.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-por-que-dominar-os-tipos-de-teste">Por que dominar os tipos de teste?</h2>
<p>Dominar os tipos de teste é o primeiro passo para garantir entregas com qualidade.<br />Cada tipo tem um <strong>objetivo</strong>, uma <strong>fase ideal</strong> de aplicação e um <strong>impacto direto</strong> na qualidade do produto.</p>
<p>Quando o QA compreende <strong>o que precisa ser validado e como</strong>, ele consegue detectar falhas mais cedo, reduzir custos de correção e contribuir para um produto mais estável e confiável.</p>
<h2 id="heading-1-teste-unitario">🔍 1. Teste Unitário</h2>
<p><strong>Objetivo:</strong> Validar o funcionamento isolado de partes pequenas do código (funções, métodos, classes).<br /><strong>Responsável:</strong> Normalmente o desenvolvedor.<br /><strong>Ferramentas:</strong> Jest, JUnit, NUnit, PyTest.</p>
<blockquote>
<p>💡 É o primeiro nível de verificação. Ajuda a detectar erros logo no início do desenvolvimento.</p>
</blockquote>
<hr />
<h2 id="heading-2-teste-de-integracao">🧩 2. Teste de Integração</h2>
<p><strong>Objetivo:</strong> Garantir que diferentes módulos do sistema funcionem corretamente em conjunto.<br /><strong>Responsável:</strong> QA ou desenvolvedor.<br /><strong>Ferramentas:</strong> Postman, Newman, Supertest.</p>
<blockquote>
<p>💬 Exemplo: testar se o módulo de login comunica-se corretamente com o banco de dados e o sistema de autenticação.</p>
</blockquote>
<hr />
<h2 id="heading-3-teste-de-sistema">🌐 3. Teste de Sistema</h2>
<p><strong>Objetivo:</strong> Validar o sistema como um todo, garantindo que todas as funcionalidades atendam aos requisitos.<br /><strong>Responsável:</strong> QA.<br /><strong>Ferramentas:</strong> Selenium, Cypress, Playwright.</p>
<blockquote>
<p>🧭 É aqui que se verifica a aplicação de ponta a ponta, simulando o comportamento real do usuário.</p>
</blockquote>
<hr />
<h2 id="heading-4-teste-de-aceitacao">👥 4. Teste de Aceitação</h2>
<p><strong>Objetivo:</strong> Confirmar se o sistema atende às expectativas e requisitos do cliente.<br /><strong>Responsável:</strong> QA e cliente.<br /><strong>Ferramentas:</strong> Cucumber, Behave.</p>
<blockquote>
<p>✅ Normalmente é a última fase antes da entrega do produto.</p>
</blockquote>
<hr />
<h2 id="heading-5-teste-de-regressao">⚙️ 5. Teste de Regressão</h2>
<p><strong>Objetivo:</strong> Garantir que novas alterações no código não afetaram funcionalidades já existentes.<br /><strong>Responsável:</strong> QA (com foco em automação).<br /><strong>Ferramentas:</strong> Cypress, Selenium, Jenkins (CI/CD).</p>
<blockquote>
<p>🔁 É essencial após correções de bugs e novas implementações.</p>
</blockquote>
<hr />
<h2 id="heading-6-teste-de-performance">🚀 6. Teste de Performance</h2>
<p><strong>Objetivo:</strong> Avaliar o desempenho, escalabilidade e estabilidade da aplicação sob diferentes cargas de uso.<br /><strong>Responsável:</strong> QA especializado.<br /><strong>Ferramentas:</strong> JMeter, Gatling, k6.</p>
<blockquote>
<p>📊 Mede tempo de resposta, uso de recursos e comportamento em cenários de estresse.</p>
</blockquote>
<hr />
<h2 id="heading-7-teste-de-seguranca">🔒 7. Teste de Segurança</h2>
<p><strong>Objetivo:</strong> Identificar vulnerabilidades e falhas que possam ser exploradas por ataques.<br /><strong>Responsável:</strong> QA de segurança ou equipe especializada.<br /><strong>Ferramentas:</strong> OWASP ZAP, Burp Suite.</p>
<blockquote>
<p>🛡️ Protege os dados dos usuários e garante a conformidade com normas de segurança.</p>
</blockquote>
<hr />
<h2 id="heading-8-teste-de-usabilidade">📱 8. Teste de Usabilidade</h2>
<p><strong>Objetivo:</strong> Avaliar a experiência do usuário (UX) — clareza, acessibilidade e facilidade de uso.<br /><strong>Responsável:</strong> QA em conjunto com equipe de UX/UI.<br /><strong>Ferramentas:</strong> Hotjar, Maze, testes A/B.</p>
<blockquote>
<p>👀 O foco é o usuário final — quanto mais simples e intuitiva a aplicação, melhor.</p>
</blockquote>
<hr />
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768400927019/1e7de687-f201-418c-89bb-1babd4a0ffab.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-conclusao">💡 Conclusão</h2>
<p>Ser QA é muito mais do que testar funcionalidades. É <strong>garantir qualidade desde o início do processo de desenvolvimento</strong>.</p>
<p>Dominar os tipos de teste permite uma visão ampla sobre o produto, antecipando riscos e entregando valor real ao usuário.</p>
<blockquote>
<p>“Qualidade não se adiciona no final, ela é construída em cada etapa do desenvolvimento.”</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Padronização e Clareza no Controle de Versão]]></title><description><![CDATA[O que é e para que serve
Conventional Commits é uma convenção para escrever mensagens de commit de forma estruturada e padronizada. Ele define um formato claro para facilitar a leitura, automação de processos e compreensão do histórico de mudanças em...]]></description><link>https://areadev.com.br/padronizacao-e-clareza-no-controle-de-versao</link><guid isPermaLink="true">https://areadev.com.br/padronizacao-e-clareza-no-controle-de-versao</guid><category><![CDATA[Git]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[GitLab]]></category><category><![CDATA[github-actions]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Fri, 21 Jun 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754325500156/8b7d3f4b-6feb-4fa5-8a9a-f13d9a44021b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-o-que-e-e-para-que-serve">O que é e para que serve</h2>
<p><strong>Conventional Commits</strong> é uma convenção para escrever mensagens de commit de forma <strong>estruturada e padronizada</strong>. Ele define um formato claro para facilitar a leitura, automação de processos e compreensão do histórico de mudanças em um projeto.</p>
<p>Essa convenção é especialmente útil em projetos com múltiplos colaboradores, pois melhora:</p>
<ul>
<li><p>A <strong>comunicação</strong> entre os membros da equipe;</p>
</li>
<li><p>A <strong>geração automatizada de changelogs</strong>;</p>
</li>
<li><p>A <strong>identificação de versões semânticas (SemVer)</strong>;</p>
</li>
<li><p>A integração com ferramentas de CI/CD (como GitHub Actions e Semantic Release).</p>
</li>
</ul>
<p>A ideia central é prefixar as mensagens com <strong>tipos de alterações</strong> (como <code>feat</code>, <code>fix</code>, <code>docs</code>, etc.), seguidos de uma breve descrição.</p>
<p>Por exemplo:</p>
<pre><code class="lang-bash">feat: adicionar página de login
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768404709592/f715d212-83f8-4f41-81da-f2c861de5769.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-iniciando-o-uso">Iniciando o uso</h2>
<p>Para adotar a convenção Conventional Commits no seu projeto, siga estes passos:</p>
<ol>
<li><p><strong>Familiarize-se com a estrutura padrão:</strong></p>
<pre><code class="lang-bash"> &lt;tipo&gt;[!][(escopo)]: &lt;descrição curta&gt;
</code></pre>
<p> Onde:</p>
<ul>
<li><p><code>tipo</code>: tipo da mudança (<code>feat</code>, <code>fix</code>, <code>docs</code>, etc.).</p>
</li>
<li><p><code>escopo</code> (opcional): onde a mudança ocorreu (ex: <code>login</code>, <code>api</code>, <code>header</code>).</p>
</li>
<li><p><code>!</code>: indica uma <strong>mudança que quebra compatibilidade</strong> (breaking change).</p>
</li>
<li><p><code>descrição curta</code>: explicação clara e objetiva da mudança.</p>
</li>
</ul>
</li>
<li><p><strong>Tipos mais comuns:</strong></p>
<ul>
<li><p><code>feat</code>: uma nova funcionalidade</p>
</li>
<li><p><code>fix</code>: correção de bug</p>
</li>
<li><p><code>docs</code>: mudanças na documentação</p>
</li>
<li><p><code>style</code>: ajustes de formatação (espaços, ponto e vírgula, etc.)</p>
</li>
<li><p><code>refactor</code>: refatorações sem alterar comportamento</p>
</li>
<li><p><code>test</code>: adição ou ajuste de testes</p>
</li>
<li><p><code>chore</code>: tarefas que não afetam o código de produção (ex: scripts, configs)</p>
</li>
</ul>
</li>
<li><p><strong>Ferramentas úteis:</strong></p>
<ul>
<li><p><code>commitlint</code>: valida mensagens de commit.</p>
</li>
<li><p><code>husky</code>: aplica hooks no Git para rodar o commitlint automaticamente.</p>
</li>
<li><p><code>semantic-release</code>: gera changelogs e publica versões automaticamente com base nos commits.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-exemplos-praticos">Exemplos práticos</h2>
<p>Aqui estão alguns exemplos de mensagens de commit seguindo a convenção:</p>
<pre><code class="lang-bash">feat(auth): adicionar autenticação via Google
fix(api): corrigir erro 500 ao buscar usuários inativos
docs(readme): atualizar instruções de instalação
style(header): remover espaço extra no CSS
refactor(user-service): otimizar função de login
<span class="hljs-built_in">test</span>(profile): adicionar testes para edição de perfil
chore(ci): configurar pipeline <span class="hljs-keyword">do</span> GitHub Actions
</code></pre>
<p><strong>Breaking changes:</strong></p>
<pre><code class="lang-bash">feat!: remover suporte à versão antiga da API
</code></pre>
<p>Ou, em uma mensagem de commit multi-linha:</p>
<pre><code class="lang-bash">refactor(core): remover função obsoleta de validação

BREAKING CHANGE: a função validateOldInput foi removida e substituída por validateInput.
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768404723951/70d1002e-0439-47d5-943e-121381e5a3c7.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-conclusao">Conclusão</h2>
<p>Adotar a convenção <strong>Conventional Commits</strong> é um pequeno passo que traz grandes benefícios para o desenvolvimento de software. A padronização das mensagens melhora a colaboração, facilita automações e garante um histórico mais compreensível e útil.</p>
<p>Seja em projetos pessoais ou em grandes equipes, aplicar essa convenção contribui diretamente para a <strong>manutenibilidade</strong>, <strong>escalabilidade</strong> e <strong>profissionalismo</strong> do código.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Conventional Commits - Official Specification <a target="_self" href="https://www.conventionalcommits.org/en/v1.0.0/#summary">https://www.conventionalcommits.org/en/v1.0.0/#summary</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Commitlint Documentation - <a target="_self" href="https://commitlint.js.org/#/">https://commitlint.js.org/#/</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Semantic Release Guide - <a target="_self" href="https://semantic-release.gitbook.io/">https://semantic-release.gitbook.io/</a></div>
</div>]]></content:encoded></item><item><title><![CDATA[Eficiência e Escalabilidade com Docker]]></title><description><![CDATA[Nos últimos anos, Docker emergiu como uma tecnologia revolucionária no mundo da computação. Com sua capacidade de criar, implantar e executar aplicativos de maneira rápida e consistente, Docker não é apenas uma ferramenta, mas sim uma mudança de para...]]></description><link>https://areadev.com.br/eficiencia-e-escalabiliadade-com-docker</link><guid isPermaLink="true">https://areadev.com.br/eficiencia-e-escalabiliadade-com-docker</guid><category><![CDATA[Docker]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Tue, 18 Jun 2024 17:36:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1718732588671/97d953b2-fc2d-4c18-9287-827e4d717fd1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Nos últimos anos, Docker emergiu como uma tecnologia revolucionária no mundo da computação. Com sua capacidade de criar, implantar e executar aplicativos de maneira rápida e consistente, Docker não é apenas uma ferramenta, mas sim uma mudança de paradigma na forma como desenvolvemos e distribuímos software. Este artigo explora os fundamentos do Docker, seus benefícios e como você pode começar a aproveitá-lo para transformar seu desenvolvimento e operações de TI.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768406985430/ee08661c-1769-4868-bc21-c337e986d063.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-o-que-e-docker">O que é Docker?</h3>
<p>Docker é uma plataforma de código aberto que automatiza a implantação de aplicativos dentro de contêineres de software. Esses contêineres permitem que um aplicativo seja empacotado com todas as suas dependências e bibliotecas necessárias, garantindo que ele funcione de maneira consistente em qualquer ambiente onde Docker esteja sendo executado.</p>
<h3 id="heading-beneficios-de-utilizar-docker">Benefícios de Utilizar Docker</h3>
<ol>
<li><p><strong>Portabilidade e Consistência</strong>: Com Docker, você pode empacotar seu aplicativo e suas dependências em um contêiner, garantindo que ele se comporte da mesma maneira, independentemente do ambiente de desenvolvimento, teste ou produção.</p>
</li>
<li><p><strong>Eficiência de Recursos</strong>: Contêineres Docker compartilham o núcleo do sistema operacional host, o que os torna mais leves em comparação com máquinas virtuais tradicionais, resultando em maior eficiência de recursos e custos reduzidos.</p>
</li>
<li><p><strong>Escalabilidade</strong>: Docker facilita a escalabilidade horizontal e vertical, permitindo que você dimensione seus aplicativos de acordo com a demanda, de forma rápida e eficiente.</p>
</li>
<li><p><strong>Facilidade de Gerenciamento</strong>: Com Docker, é possível automatizar tarefas de implantação, atualização e manutenção de aplicativos, reduzindo significativamente a carga operacional sobre equipes de TI.</p>
</li>
</ol>
<h3 id="heading-como-comecar-com-docker">Como Começar com Docker</h3>
<p>Para começar a aproveitar os benefícios do Docker, siga estes passos básicos:</p>
<ol>
<li><p><strong>Instalação</strong>: Baixe e instale o Docker Engine em seu sistema operacional. Docker oferece suporte para Windows, macOS e Linux, facilitando a integração em diversos ambientes de desenvolvimento.</p>
 <div data-node-type="callout">
 <div data-node-type="callout-emoji">💡</div>
 <div data-node-type="callout-text"><a target="_blank" href="https://docs.docker.com/desktop/install/linux-install/">https://docs.docker.com/desktop/install/linux-install/</a></div>
 </div>

<p> Por exemplo, no Linux, você pode usar o comando:</p>
<pre><code class="lang-bash"> sudo apt-get install docker-ce
</code></pre>
</li>
<li><p><strong>Criação de Imagens</strong>: Utilize Dockerfiles para definir o ambiente e as dependências do seu aplicativo. Isso permite que você crie imagens Docker personalizadas que podem ser compartilhadas e reutilizadas por toda a equipe de desenvolvimento.</p>
<p> Crie um Dockerfile para um aplicativo Node.js. Por exemplo:</p>
<pre><code class="lang-dockerfile"> <span class="hljs-keyword">FROM</span> node:<span class="hljs-number">14</span>
 <span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>
 <span class="hljs-keyword">COPY</span><span class="bash"> package.json .</span>
 <span class="hljs-keyword">RUN</span><span class="bash"> npm install</span>
 <span class="hljs-keyword">COPY</span><span class="bash"> . .</span>
 <span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"npm"</span>, <span class="hljs-string">"start"</span>]</span>
</code></pre>
</li>
<li><p><strong>Execução de Contêineres</strong>: Uma vez que sua imagem Docker esteja pronta, você pode executá-la como um contêiner. Isso cria uma instância isolada do seu aplicativo que pode ser escalada horizontalmente conforme necessário.</p>
<p> Execute o contêiner do Node.js com:</p>
<pre><code class="lang-bash"> docker build -t meu-app .
 docker run -p 3000:3000 meu-app
</code></pre>
</li>
<li><p><strong>Implantação em Produção</strong>: Para ambientes de produção, utilize orquestradores como Kubernetes ou Docker Swarm para gerenciar múltiplos contêineres Docker e automatizar tarefas de implantação e monitoramento.</p>
<p> Use Docker Compose para orquestrar múltiplos contêineres. Por exemplo, um arquivo <code>docker-compose.yml</code> para um aplicativo com front-end React e back-end Node.js:</p>
<pre><code class="lang-yaml"> <span class="hljs-attr">version:</span> <span class="hljs-string">'3'</span>
 <span class="hljs-attr">services:</span>
   <span class="hljs-attr">web:</span>
     <span class="hljs-attr">build:</span> <span class="hljs-string">./frontend</span>
     <span class="hljs-attr">ports:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-string">"3000:3000"</span>
   <span class="hljs-attr">api:</span>
     <span class="hljs-attr">build:</span> <span class="hljs-string">./backend</span>
     <span class="hljs-attr">ports:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-string">"4000:4000"</span>
</code></pre>
</li>
</ol>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768406998118/408fd43a-4fba-43b1-ab17-8e05d06dacfd.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-consideracoes-finais">Considerações Finais</h3>
<p>Docker representa mais do que uma simples ferramenta; é um catalisador para a inovação e eficiência na entrega de software. Ao adotar Docker, as equipes de desenvolvimento podem acelerar o ciclo de vida do desenvolvimento, melhorar a consistência operacional e reduzir os custos de infraestrutura.</p>
<p>Em resumo, Docker não é apenas sobre contêineres; é sobre capacitar equipes de desenvolvimento a alcançar novos níveis de desempenho e escalabilidade. Comece sua jornada com Docker hoje e descubra como essa tecnologia transformará seu fluxo de trabalho de desenvolvimento para melhor.</p>
<p>Este artigo foi projetado não apenas para explicar os conceitos fundamentais do Docker, mas também para engajar e educar seus leitores sobre o poder desta ferramenta inovadora. Ao otimizar para SEO, garantimos que este conteúdo seja descoberto por aqueles que buscam entender melhor Docker e suas aplicações práticas.</p>
<p>Se você está pronto para embarcar na revolução Docker, comece agora mesmo e prepare-se para transformar sua abordagem de desenvolvimento de software.</p>
]]></content:encoded></item><item><title><![CDATA[Instalando MongoDB Compass no linux]]></title><description><![CDATA[Introdução:
O MongoDB Compass é uma ferramenta gráfica poderosa que facilita a exploração e manipulação de bancos de dados MongoDB. Com recursos intuitivos e flexíveis, o Compass oferece visualizações detalhadas de esquemas, métricas de desempenho em...]]></description><link>https://areadev.com.br/instalando-mongodb-compass-no-linux</link><guid isPermaLink="true">https://areadev.com.br/instalando-mongodb-compass-no-linux</guid><category><![CDATA[Databases]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Tue, 18 Jun 2024 03:00:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1718201067983/bd7025c4-99f4-451c-abac-226d03016ffd.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410249475/4bf95070-0cbe-4c1e-83ff-b637cc9d9b3b.jpeg" alt class="image--center mx-auto" /></a></p>
<p><strong>Introdução:</strong></p>
<p>O MongoDB Compass é uma ferramenta gráfica poderosa que facilita a exploração e manipulação de bancos de dados MongoDB. Com recursos intuitivos e flexíveis, o Compass oferece visualizações detalhadas de esquemas, métricas de desempenho em tempo real e capacidades avançadas de consulta.</p>
<p>Acesse o site oficial do MongoDB Compass em <a target="_blank" href="https://www.mongodb.com/docs/compass/master/install/">https://www.mongodb.com/docs/compass/master/install/</a></p>
<p><strong>Passo 1:</strong> Download MongoDB Compass</p>
<pre><code class="lang-bash">wget https://downloads.mongodb.com/compass/mongodb-compass_1.43.0_amd64.deb
</code></pre>
<p><strong>Passo 2:</strong> Install MongoDB Compass</p>
<pre><code class="lang-bash">sudo dpkg -i mongodb-compass_1.43.0_amd64.deb
</code></pre>
<p><strong>Passo 3:</strong> Start MongoDB Compass</p>
<pre><code class="lang-bash">mongodb-compass
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718199602913/d4aef5dc-ca6b-40a3-b879-ac955a6b3b4a.png" alt="Download MongoDB Compass" class="image--center mx-auto" /></p>
<p><strong>Passo 4:</strong> Configurar o MongoDB Compass<br />Ao iniciar o MongoDB Compass pela primeira vez, você será guiado por um processo de configuração inicial para definir suas preferências, como idioma e tema da interface. Siga as instruções na tela para concluir a configuração.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718200050090/64d0a3a4-a87e-4c2e-8dd1-ce64f3995d5c.png" alt="Configurando o MongoDB Compass " class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718200115650/98b33ff6-0faa-4fbd-a8b8-7bb76aac5132.png" alt="Configurando o MongoDB Compass " class="image--center mx-auto" /></p>
<p><strong>Passo 5:</strong> Usar o MongoDB Compass<br />Com o MongoDB Compass instalado e configurado, você está pronto para explorar seus bancos de dados MongoDB, examinar esquemas, executar consultas avançadas e muito mais.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1718200172440/67b834f7-cb6b-432b-ac7d-624f6c6e644a.png" alt="Usar o MongoDB Compass" class="image--center mx-auto" /></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" href="https://www.mongodb.com/docs/compass/master/install/">https://www.mongodb.com/docs/compass/master/install/</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" href="https://www.mongodb.com/try/download/compass">https://www.mongodb.com/try/download/compass</a></div>
</div>

<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410257582/37a7e3e4-ac64-436e-8ec1-d485271881a9.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao"><strong>Conclusão:</strong></h3>
<p>Lembre-se de que o MongoDB Compass está disponível em diferentes versões, atendendo a diferentes necessidades. Certifique-se de escolher a versão correta durante o processo de download.</p>
<p>Espero que este tutorial seja útil para você começar a usar o MongoDB Compass no Linux. Se tiver alguma dúvida, não hesite em perguntar.</p>
]]></content:encoded></item><item><title><![CDATA[Deploy de Aplicações Laravel]]></title><description><![CDATA[Introdução
O deploy de uma aplicação Laravel envolve a implantação da aplicação em um ambiente de produção, onde os usuários podem acessá-la. É um processo crucial que requer cuidado e atenção para garantir que a aplicação seja implantada de forma se...]]></description><link>https://areadev.com.br/deploy-de-aplicacoes-laravel</link><guid isPermaLink="true">https://areadev.com.br/deploy-de-aplicacoes-laravel</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Mon, 17 Jun 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717784048946/e25e1a4a-76ed-46ea-9d21-b278472d2e2d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410325761/80b51eb9-bac8-47b1-953a-4bc9f9ad46b3.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-introducao">Introdução</h4>
<p>O deploy de uma aplicação Laravel envolve a implantação da aplicação em um ambiente de produção, onde os usuários podem acessá-la. É um processo crucial que requer cuidado e atenção para garantir que a aplicação seja implantada de forma segura e eficiente.</p>
<h4 id="heading-pre-requisitos">Pré-requisitos</h4>
<p>Antes de iniciar o processo de deploy, certifique-se de que sua aplicação Laravel está pronta para produção. Isso inclui:</p>
<ul>
<li><p>Otimização do ambiente de produção, como configurar o servidor web (por exemplo, Nginx ou Apache) e o servidor de aplicação (por exemplo, PHP-FPM).</p>
</li>
<li><p>Configuração do arquivo <code>.env</code> com as variáveis de ambiente corretas para o ambiente de produção.</p>
</li>
<li><p>Execução de testes automatizados para garantir que a aplicação esteja livre de bugs.</p>
</li>
</ul>
<h4 id="heading-opcoes-de-hospedagem">Opções de Hospedagem</h4>
<p>Existem várias opções disponíveis para hospedar uma aplicação Laravel em um ambiente de produção:</p>
<ol>
<li><p>Servidores VPS (Virtual Private Server): Como DigitalOcean, Linode, AWS EC2.</p>
</li>
<li><p>Plataformas de Hospedagem Gerenciada: Como Heroku, Laravel Forge, <a target="_blank" href="http://Platform.sh">Platform.sh</a>.</p>
</li>
<li><p>Serviços de Hospedagem Compartilhada: Como SiteGround, Bluehost, HostGator.</p>
</li>
</ol>
<p>Escolha a opção de hospedagem que melhor atenda às necessidades da sua aplicação e às suas preferências de configuração e gerenciamento.</p>
<h4 id="heading-processo-de-deploy">Processo de Deploy</h4>
<p>O processo de deploy de uma aplicação Laravel geralmente envolve os seguintes passos:</p>
<ol>
<li><p><strong>Preparação do Ambiente de Produção</strong>: Configure o servidor e o ambiente de produção para hospedar a aplicação Laravel.</p>
</li>
<li><p><strong>Transferência dos Arquivos</strong>: Envie os arquivos da aplicação Laravel para o servidor de produção usando SSH, FTP ou ferramentas de deploy automatizadas.</p>
</li>
<li><p><strong>Instalação de Dependências</strong>: No servidor de produção, execute <code>composer install</code> para instalar as dependências do Laravel.</p>
</li>
<li><p><strong>Configuração do Arquivo .env</strong>: Certifique-se de configurar o arquivo <code>.env</code> com as variáveis de ambiente corretas para o ambiente de produção.</p>
</li>
<li><p><strong>Execução de Migrações e Seeders</strong>: Se necessário, execute migrações e seeders no banco de dados do servidor de produção para garantir que esteja atualizado.</p>
</li>
<li><p><strong>Configuração do Servidor Web</strong>: Configure o servidor web (Nginx, Apache) para direcionar as solicitações HTTP para o diretório público da aplicação Laravel.</p>
</li>
<li><p><strong>Configuração do Cache e das Filas</strong>: Configure o cache e as filas de trabalhos para otimizar o desempenho da aplicação em produção.</p>
</li>
<li><p><strong>Monitoramento e Manutenção</strong>: Implemente ferramentas de monitoramento e agende manutenções regulares para garantir a integridade e a disponibilidade contínua da aplicação em produção.</p>
</li>
</ol>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410330918/c5f34914-986b-4890-b5ba-9ba572cd15b8.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>O deploy de uma aplicação Laravel é um processo importante que requer planejamento, preparação e execução cuidadosa. Ao seguir as práticas recomendadas e escolher a opção de hospedagem adequada, você pode implantar sua aplicação Laravel com confiança e garantir que ela esteja disponível para seus usuários de forma segura e eficiente. Nos próximos tópicos, continuaremos explorando outros aspectos avançados do desenvolvimento web com o Laravel.</p>
]]></content:encoded></item><item><title><![CDATA[Testes Automatizados]]></title><description><![CDATA[Introdução
Os testes automatizados são essenciais para garantir a qualidade e a estabilidade de uma aplicação. No Laravel, você pode escrever e executar uma variedade de testes automatizados para verificar se o seu código está funcionando conforme o ...]]></description><link>https://areadev.com.br/testes-automatizados</link><guid isPermaLink="true">https://areadev.com.br/testes-automatizados</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Fri, 14 Jun 2024 03:00:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717782780185/2a794ee8-1247-42a7-b52a-16c1b7c36a0e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410413404/dc56d5d1-b682-43da-a81f-45258bfe1b46.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-introducao">Introdução</h4>
<p>Os testes automatizados são essenciais para garantir a qualidade e a estabilidade de uma aplicação. No Laravel, você pode escrever e executar uma variedade de testes automatizados para verificar se o seu código está funcionando conforme o esperado.</p>
<h4 id="heading-tipos-de-testes">Tipos de Testes</h4>
<p>O Laravel suporta vários tipos de testes automatizados, incluindo Testes Unitários, Testes de Integração e Testes de Ponta a Ponta (End-to-End).</p>
<h5 id="heading-testes-unitarios">Testes Unitários</h5>
<p>Os Testes Unitários verificam se unidades individuais de código (como métodos de classe) funcionam conforme o esperado. Eles são rápidos de escrever e executar e ajudam a identificar bugs no código.</p>
<h5 id="heading-testes-de-integracao">Testes de Integração</h5>
<p>Os Testes de Integração verificam se componentes de uma aplicação funcionam juntos corretamente. Eles testam a interação entre várias partes do código e podem ajudar a identificar problemas de integração.</p>
<h5 id="heading-testes-de-ponta-a-ponta-end-to-end">Testes de Ponta a Ponta (End-to-End)</h5>
<p>Os Testes de Ponta a Ponta simulam a interação de um usuário com a aplicação, verificando se o sistema funciona conforme o esperado do ponto de vista do usuário final. Eles testam o fluxo completo da aplicação, desde a entrada do usuário até a saída esperada.</p>
<h4 id="heading-escrevendo-testes-no-laravel">Escrevendo Testes no Laravel</h4>
<p>O Laravel fornece uma API expressiva e poderosa para escrever testes automatizados.</p>
<h5 id="heading-criando-testes">Criando Testes</h5>
<p>Você pode criar um novo teste usando o Artisan CLI:</p>
<pre><code class="lang-bash">php artisan make:<span class="hljs-built_in">test</span> UserTest
</code></pre>
<p>Isso criará um arquivo de teste em <code>tests/Feature</code> ou <code>tests/Unit</code>, dependendo do tipo de teste que você está escrevendo.</p>
<h5 id="heading-escrevendo-testes">Escrevendo Testes</h5>
<p>Em seguida, você pode escrever os testes dentro do arquivo gerado. Por exemplo, um teste de unidade para verificar se um método retorna o resultado esperado pode ser assim:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testExample</span>(<span class="hljs-params"></span>)
    </span>{
        $result = SomeClass::someMethod();

        <span class="hljs-keyword">$this</span>-&gt;assertEquals(<span class="hljs-string">'expected result'</span>, $result);
    }</span>
</code></pre>
<h5 id="heading-executando-testes">Executando Testes</h5>
<p>Você pode executar todos os testes usando o Artisan CLI:</p>
<pre><code class="lang-bash">php artisan <span class="hljs-built_in">test</span>
</code></pre>
<p>Ou você pode executar testes em um arquivo específico:</p>
<pre><code class="lang-bash">php artisan <span class="hljs-built_in">test</span> tests/Feature/UserTest.php
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410426300/49fd8daf-c9df-47d6-be2a-d6e7e8396814.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Os testes automatizados são uma parte fundamental do desenvolvimento de software moderno. No Laravel, você pode escrever e executar uma variedade de testes automatizados para garantir que sua aplicação funcione conforme o esperado e que novas alterações não introduzam regressões ou bugs. Com uma API expressiva e poderosa para escrever testes, o Laravel facilita a implementação de uma estratégia de teste eficaz para sua aplicação. Nos próximos tópicos, continuaremos explorando outros aspectos avançados do desenvolvimento web com o Laravel.</p>
]]></content:encoded></item><item><title><![CDATA[Laravel Scheduler: Automatizando Tarefas com Commands, Jobs e Events]]></title><description><![CDATA[https://www.youtube.com/watch?v=ertkSaFs_24
* * *

Introdução
Primeiro de tudo, vamos entender o que é uma cron.
Uma cron (ou cron job) é uma tarefa agendada para executar automaticamente em determina]]></description><link>https://areadev.com.br/tarefas-agendadas-e-jobs</link><guid isPermaLink="true">https://areadev.com.br/tarefas-agendadas-e-jobs</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Thu, 13 Jun 2024 03:00:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/a94d4467-0b5b-4a5c-84b9-682b6cf8c0a9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410455383/0bd1df06-acdb-4c34-a785-89970e57a405.jpeg" alt="" style="display:block;margin:0 auto" /></a></p>
<p><a class="embed-card" href="https://www.youtube.com/watch?v=ertkSaFs_24">https://www.youtube.com/watch?v=ertkSaFs_24</a></p>
* * *

<h2>Introdução</h2>
<p>Primeiro de tudo, vamos entender o que é uma <strong>cron.</strong></p>
<p>Uma <strong>cron</strong> (ou <strong>cron job</strong>) é uma <strong>tarefa agendada para executar automaticamente em determinados horários</strong> em sistemas Linux/Unix.</p>
<p>Ela é gerenciada por um serviço chamado <strong>cron</strong>, que roda em segundo plano (um daemon) verificando o tempo e executando comandos quando chega o horário programado.</p>
<h2>Exemplo simples</h2>
<p>Imagine que você quer fazer <strong>backup do banco todo dia às 2h da manhã</strong>.<br />Você cria uma cron job que executa um comando nesse horário automaticamente.</p>
<p>Exemplo de cron:</p>
<pre><code class="language-shell">0 2 * * * php backup.php
</code></pre>
<p>Significa:</p>
<pre><code class="language-shell">┌ minuto (0 - 59)
│ ┌ hora (0 - 23)
│ │ ┌ dia do mês (1 - 31)
│ │ │ ┌ mês (1 - 12)
│ │ │ │ ┌ dia da semana (0 - 7)
│ │ │ │ │
0 2 * * * comando
</code></pre>
<p>Ou seja:</p>
<pre><code class="language-plaintext">Todo dia às 02:00 executar php backup.php
</code></pre>
<h2>Exemplos comuns de cron jobs</h2>
<ul>
<li><p>limpar arquivos temporários</p>
</li>
<li><p>rodar backups</p>
</li>
<li><p>enviar emails automáticos</p>
</li>
<li><p>executar scripts de manutenção</p>
</li>
<li><p>processar filas de jobs</p>
</li>
</ul>
<h2>Exemplo no Laravel</h2>
<p>No <strong>Laravel</strong>, normalmente você configura uma única cron no servidor:</p>
<pre><code class="language-shell">* * * * * sail artisan schedule:run
</code></pre>
<p>Isso faz o Laravel verificar <strong>a cada minuto</strong> se existe alguma tarefa agendada no:</p>
<pre><code class="language-plaintext">app/Console/Kernel.php
</code></pre>
<p>Exemplo dentro do Laravel:</p>
<pre><code class="language-plaintext">$schedule-&gt;command('emails:send')-&gt;daily();
</code></pre>
<h2>Resumindo</h2>
<p>Uma <strong>cron</strong> é basicamente:</p>
<blockquote>
<p>Um agendador automático de tarefas no servidor.</p>
</blockquote>
<p>Ele permite que programas rodem <strong>sem intervenção humana em horários específicos</strong>.</p>
<hr />
<h2>Agora vamos fazer no Laravel</h2>
<p><a class="embed-card" href="https://youtu.be/BuDPsJbfl8c">https://youtu.be/BuDPsJbfl8c</a></p>
* * *

<p>Nesse tutorial, vamos ver 3 tipos de <strong>cron</strong> ou <strong>schedules</strong> no Laravel.</p>
<ul>
<li><p>Para comandos artisan</p>
</li>
<li><p>Para jobs</p>
</li>
<li><p>Para events</p>
</li>
</ul>
<hr />
<p>Automatizar tarefas é essencial em qualquer aplicação moderna. Envio de e-mails, processamento de dados, sincronizações, limpezas automáticas… tudo isso pode (e deve) rodar fora da requisição HTTP.</p>
<p>O <strong>Laravel Scheduler</strong> resolve isso de forma elegante.</p>
<p>Neste artigo você vai aprender:</p>
<ul>
<li><p>O que é o Scheduler</p>
</li>
<li><p>Como agendar <strong>Commands</strong></p>
</li>
<li><p>Como agendar <strong>Jobs</strong></p>
</li>
<li><p>Como agendar <strong>Events</strong></p>
</li>
</ul>
<h4>O que é o Laravel Scheduler?</h4>
<p>O Scheduler permite definir tarefas agendadas diretamente no código, sem precisar criar múltiplas entradas no crontab.</p>
<p>Em vez disso, você configura <strong>apenas um cron no servidor</strong>, e o Laravel decide o que deve rodar.</p>
<p>Arquivo principal:</p>
<pre><code class="language-php">app/Console/Kernel.php
</code></pre>
<p>Comandos úteis</p>
<pre><code class="language-plaintext">- sail artisan                = Lista todos os comandos CLI
- sail artisan schedule:list  = Lista todas as tarefas agendadas
- sail artisan schedule:work  = Inicia o agendador de tarefas
- sail artisan schedule:run   = Roda todos os comandos agendados
- sail artisan queue:work     = Inicia o processamento de tarefas na fila como um daemon 
- sail artisan horizon        = Ativa o pacote do horizon
- sail artisan horizon:status = Obtenha o status atual do Horizon
- sail artisan horizon:clear  = Excluir todos os trabalhos da fila especificada

Criando um job
- sail artisan make:job TestJob

Criando um event
- sail artisan make:listener TestListener 


OBS: (daemon: é um programa que roda em segundo plano no sistema operacional, executando tarefas automaticamente sem interação direta do usuário.)
</code></pre>
<h3>Exemplo 1 — Agendando Commands Artisan</h3>
<p>Criando comando via terminal:</p>
<pre><code class="language-php">php artisan make:command TestCommand
</code></pre>
<pre><code class="language-php">&lt;?php

// Arquivo criado: app/Console/Commands/TestCommand.php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class TestCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:test-command';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        Log::info('Test command in TestCommand.php');
    }
}
</code></pre>
<p>Defina o signature:</p>
<pre><code class="language-php">protected $signature = 'app:test-command';
protected $description = 'Command description';
</code></pre>
<p>Agendando o Command<br />No <code>Kernel.php</code>:</p>
<pre><code class="language-php"> protected function schedule(Schedule $schedule)
 {
   // Command defined in app/Console/Commands/TestCommand.php
   $schedule-&gt;command('app:test-command')-&gt;everyMinute();
 }
</code></pre>
<hr />
<p><a class="embed-card" href="https://www.youtube.com/watch?v=qi6W28YfMXU">https://www.youtube.com/watch?v=qi6W28YfMXU</a></p>
* * *

<h3>Exemplo 2 — Agendando Commands Artisan</h3>
<p>No <code>routes/console.php</code>:</p>
<pre><code class="language-php">// Arquivo: routes/console.php copie e cole o código:

Artisan::command('app:my-teste', function () {
    Log::info('Test command in console.php');
})-&gt;purpose('Test command in console.php');
</code></pre>
<p>No <code>Kernel.php</code>:</p>
<pre><code class="language-php">&lt;?php
    

    use Illuminate\Console\Scheduling\Schedule;
    
    protected function schedule(Schedule $schedule)
    {
        // Command defined in rotas/console.php
        $schedule-&gt;command('app:my-teste')-&gt;when(function () {
            return User::count() &gt; 0;
        })-&gt;everyMinute();
    }
</code></pre>
<h3>Exemplo 3 — Criando um Job</h3>
<pre><code class="language-php">php artisan make:job TestJob
</code></pre>
<pre><code class="language-php">// Arquivo: app/jobs/TestJob.php

public function handle(): void
{
   Log::info('Test job executed at ' . now());
}
</code></pre>
<p>Arquivo kernel.php:</p>
<pre><code class="language-php">&lt;?php
    use Illuminate\Console\Scheduling\Schedule;
    
    protected function schedule(Schedule $schedule)
    {
        // Job defined in app/Jobs/TestJob.php
        $schedule-&gt;job(TestJob::class)-&gt;everyMinute();
    }
</code></pre>
<p>Isso significa:</p>
<ul>
<li><p>A cada minuto é executado</p>
</li>
<li><p>O job é enviado para a fila (Queue)</p>
</li>
<li><p>Worker processa em background</p>
</li>
</ul>
<p>Execute no terminal:</p>
<pre><code class="language-shell">sail artisan schedule:list 
</code></pre>
<p>Lista todas as tarefas agendadas.</p>
<pre><code class="language-shell">
sail artisan schedule:work
</code></pre>
<p>Inicia o trabalhador agendado</p>
<hr />
<p><a class="embed-card" href="https://www.youtube.com/watch?v=H4sTONx9Mio">https://www.youtube.com/watch?v=H4sTONx9Mio</a></p>
* * *

<h3>Exemplo 4 — Agendando um event</h3>
<p>No arquivo Providers/EventServiceProvider.php adicione:</p>
<pre><code class="language-php">protected $listen = [
   Registered::class =&gt; [
     SendEmailVerificationNotification::class,
   ],
   ScheduledTaskStarting::class =&gt; [
     TestListener::class,
   ],
],
</code></pre>
<p>Criando um listener:</p>
<pre><code class="language-shell">php artisan make:listener TestListener
</code></pre>
<pre><code class="language-php">&lt;?php

namespace App\Listeners;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;

class TestListener
{
    /**
     * Create the event listener.
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     */
    public function handle(object $event): void
    {
        Log::info('TestListener handled event: ' . get_class($event) . ' at ' . now());
    }
}
</code></pre>
<p>Na pasta Providers tem um arquivo chamado: EventServiceProvider.php</p>
<pre><code class="language-php">&lt;?php
// File in app/Providers/EventServiceProvider.php
namespace App\Providers;

use App\Listeners\TestListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Console\Events\ScheduledTaskStarting;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use PHPUnit\Metadata\Test;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event to listener mappings for the application.
     *
     * @var array&lt;class-string, array&lt;int, class-string&gt;&gt;
     */
    protected $listen = [
        Registered::class =&gt; [
            SendEmailVerificationNotification::class,
        ],
        ScheduledTaskStarting::class =&gt; [
            TestListener::class,
        ],
    ];

    /**
     * Register any events for your application.
     */
    public function boot(): void
    {
        //
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     */
    public function shouldDiscoverEvents(): bool
    {
        return false;
    }
}
</code></pre>
<p>Defina a classe do evento criado dentro de <strong>ScheduledTaskStarting</strong></p>
<pre><code class="language-php">ScheduledTaskStarting::class =&gt; [
 TestListener::class,
],
</code></pre>
<p>Execute:</p>
<pre><code class="language-php">sail artisan schedule:run
</code></pre>
<p>Agora veja o evento sendo executado no log.</p>
<hr />
<p>Arquivo kernel.php completo:</p>
<pre><code class="language-php">&lt;?php

namespace App\Console;

use App\Jobs\TestJob;
use App\Models\User;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
        // Command defined in app/Console/Commands/TestCommand.php
        $schedule-&gt;command('app:test-command')-&gt;everyMinute();

        // Command defined in rotas/console.php
        $schedule-&gt;command('app:my-teste')-&gt;when(function () {
            return User::count() &gt; 0;
        })-&gt;everyMinute();

        // Job defined in app/Jobs/TestJob.php
        $schedule-&gt;job(TestJob::class)-&gt;everyMinute();

    }

    /**
     * Register the commands for the application.
     */
    protected function commands(): void
    {
        $this-&gt;load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
</code></pre>
<p>No arquivo de log, podemos visualizar todos os logs que definimos no código. local: storage/laravel.log</p>
<hr />
<p>Links importantes:</p>
<p><a href="https://crontab.cronhub.io/">crontab.cronhub.io</a><br /><a href="https://laravel.com/docs/10.x/scheduling#introduction">documentação do laravel</a></p>
<hr />
<p><a href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768410463988/fe2bb649-a833-4462-ae56-faa9004ad8ee.jpeg" alt="" style="display:block;margin:0 auto" /></a></p>
<h3>Conclusão</h3>
<p>O Laravel Scheduler centraliza e organiza a automação de tarefas da aplicação.<br />Ele torna o código mais limpo, evita configurações manuais no servidor e facilita a manutenção.</p>
<p>Quando combinado com Jobs, ele permite criar sistemas automatizados, escaláveis e robustos de forma elegante.</p>
]]></content:encoded></item><item><title><![CDATA[APIs e Laravel Sanctum]]></title><description><![CDATA[https://youtu.be/YoWNa_U8zaU
 

Introdução
Ao desenvolver APIs com Laravel, um dos pontos mais importantes é garantir que apenas usuários autorizados consigam acessar determinados endpoints. Para isso, o Laravel oferece o Laravel Sanctum, uma solução...]]></description><link>https://areadev.com.br/apis-e-laravel-sanctum</link><guid isPermaLink="true">https://areadev.com.br/apis-e-laravel-sanctum</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Wed, 12 Jun 2024 03:00:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717782133815/9facb4df-d145-4c50-bad8-d4ed68fb8027.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/YoWNa_U8zaU">https://youtu.be/YoWNa_U8zaU</a></div>
<p> </p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768416412584/0a9c7348-a53d-4018-9a0e-bac9b0d1e527.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-introducao">Introdução</h4>
<p>Ao desenvolver APIs com Laravel, um dos pontos mais importantes é garantir que apenas usuários autorizados consigam acessar determinados endpoints. Para isso, o Laravel oferece o <strong>Laravel Sanctum</strong>, uma solução simples, moderna e oficial para autenticação de APIs e aplicações SPA.</p>
<p>O Sanctum foi criado para resolver dois cenários muito comuns:</p>
<ul>
<li><p>Autenticação de <strong>APIs via tokens</strong></p>
</li>
<li><p>Autenticação de <strong>SPAs (Single Page Applications)</strong> usando cookies e sessão</p>
</li>
</ul>
<p>Diferente de soluções mais complexas como OAuth2 (Laravel Passport), o Sanctum foca em <strong>simplicidade, segurança e produtividade</strong>, sendo ideal para a maioria dos projetos.</p>
<p>Neste tutorial, você vai entender como o Sanctum funciona, as diferenças entre os tipos de autenticação e como instalá-lo corretamente em um projeto Laravel.</p>
<h2 id="heading-como-funciona-o-laravel-sanctum">Como funciona o Laravel Sanctum</h2>
<p>O Laravel Sanctum funciona oferecendo uma camada de autenticação baseada em dois conceitos principais:</p>
<h3 id="heading-tokens-pessoais-personal-access-tokens">🔐 Tokens pessoais (Personal Access Tokens)</h3>
<ul>
<li><p>Cada usuário pode ter <strong>um ou vários tokens</strong></p>
</li>
<li><p>Cada token é armazenado no banco de dados</p>
</li>
<li><p>O cliente envia o token no header <code>Authorization: Bearer</code></p>
</li>
</ul>
<p>Internamente:</p>
<ul>
<li><p>O token é gerado uma única vez (plain text)</p>
</li>
<li><p>Apenas o <strong>hash do token</strong> é salvo no banco</p>
</li>
<li><p>O Laravel valida automaticamente o token a cada requisição</p>
</li>
</ul>
<h3 id="heading-autenticacao-baseada-em-cookies-spa">🍪 Autenticação baseada em cookies (SPA)</h3>
<ul>
<li><p>Usa sessões do Laravel</p>
</li>
<li><p>Proteção automática contra CSRF</p>
</li>
<li><p>Ideal para aplicações frontend (React, Vue, etc.)</p>
</li>
</ul>
<p>Nesse modo:</p>
<ul>
<li><p>O frontend solicita um cookie CSRF</p>
</li>
<li><p>O login cria uma sessão autenticada</p>
</li>
<li><p>As requisições seguintes usam cookies HttpOnly</p>
</li>
</ul>
<p>O grande diferencial do Sanctum é permitir <strong>esses dois fluxos no mesmo projeto</strong>, sem conflito.</p>
<h2 id="heading-diferenca-entre-tokens-de-api-e-autenticacao-spa">Diferença entre Tokens de API e Autenticação SPA</h2>
<p>Essa é uma das partes mais importantes de entender antes de usar o Sanctum.</p>
<h3 id="heading-tokens-de-api">🔹 Tokens de API</h3>
<p><strong>Indicado para:</strong></p>
<ul>
<li><p>Aplicativos mobile</p>
</li>
<li><p>Integrações de terceiros</p>
</li>
<li><p>APIs públicas ou privadas</p>
</li>
<li><p>Sistemas externos</p>
</li>
</ul>
<p><strong>Características:</strong></p>
<ul>
<li><p>Stateless (sem sessão)</p>
</li>
<li><p>Token enviado no header</p>
</li>
<li><p>Fácil de testar com Postman / Insomnia</p>
</li>
<li><p>Pode ter permissões (abilities)</p>
</li>
</ul>
<p><strong>Exemplo de header:</strong></p>
<pre><code class="lang-bash">Authorization: Bearer 1|xYzAbC123...
</code></pre>
<h3 id="heading-autenticacao-spa-cookies">🔹 Autenticação SPA (Cookies)</h3>
<p><strong>Indicado para:</strong></p>
<ul>
<li><p>React, Vue, Angular</p>
</li>
<li><p>Frontend no mesmo domínio ou subdomínio</p>
</li>
<li><p>Aplicações web modernas</p>
</li>
</ul>
<p><strong>Características:</strong></p>
<ul>
<li><p>Usa sessão do Laravel</p>
</li>
<li><p>Cookies HttpOnly</p>
</li>
<li><p>Proteção CSRF</p>
</li>
<li><p>Mais seguro contra XSS</p>
</li>
</ul>
<p><strong>Fluxo resumido:</strong></p>
<ol>
<li><p><code>/sanctum/csrf-cookie</code></p>
</li>
<li><p><code>/login</code></p>
</li>
<li><p>Requisições autenticadas automaticamente</p>
</li>
</ol>
<h3 id="heading-comparacao-rapida">🧠 Comparação rápida</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Característica</strong></td><td><strong>Token API</strong></td><td><strong>SPA</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Usa sessão</td><td>❌ Não</td><td>✅ Sim</td></tr>
<tr>
<td>Usa cookies</td><td>❌ Não</td><td>✅ Sim</td></tr>
<tr>
<td>Header Authorization</td><td>✅ Sim</td><td>❌ Não</td></tr>
<tr>
<td>CSRF</td><td>❌ Não</td><td>✅ Sim</td></tr>
<tr>
<td>Ideal para mobile</td><td>✅ Sim</td><td>❌ Não</td></tr>
</tbody>
</table>
</div><blockquote>
<p>As versões mais recentes do Laravel já incluem o Laravel Sanctum. No entanto, se o arquivo composer.json da sua aplicação não incluir o pacote laravel/sanctum, você pode seguir as instruções de instalação abaixo.</p>
</blockquote>
<h2 id="heading-instalacao-passo-a-passo">Instalação – Passo a passo</h2>
<p>⚠️ <strong>Observação:</strong> Neste projeto, o Sanctum já está presente no <code>composer.json</code>, então não é necessário rodar <code>composer require laravel/sanctum</code>.</p>
<h3 id="heading-passo-1-verificar-dependencia-no-composerjson">Passo 1 – Verificar dependência no <code>composer.json</code>:</h3>
<pre><code class="lang-json"><span class="hljs-string">"laravel/sanctum"</span>: <span class="hljs-string">"^3.3"</span>
</code></pre>
<p>Se estiver presente, o pacote já está instalado.</p>
<h3 id="heading-passo-2-publicar-configuracoes">Passo 2 – Publicar configurações</h3>
<pre><code class="lang-bash">php artisan vendor:publish --provider=<span class="hljs-string">"Laravel\Sanctum\SanctumServiceProvider"</span>
</code></pre>
<p>Isso cria:</p>
<ul>
<li><p><code>config/sanctum.php</code></p>
</li>
<li><p>migrations necessárias</p>
</li>
</ul>
<h3 id="heading-passo-3-rodar-as-migrations">Passo 3 – Rodar as migrations</h3>
<pre><code class="lang-bash">php artisan migrate
</code></pre>
<p>Será criada a tabela:</p>
<ul>
<li><code>personal_access_tokens</code></li>
</ul>
<h3 id="heading-passo-4-configurar-o-model-user">Passo 4 – Configurar o Model User</h3>
<p>No arquivo <code>app/Models/User.php</code>:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Laravel</span>\<span class="hljs-title">Sanctum</span>\<span class="hljs-title">HasApiTokens</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Authenticatable</span>
</span>{
    <span class="hljs-keyword">use</span> <span class="hljs-title">HasApiTokens</span>;
}
</code></pre>
<p>Sem esse trait, não é possível gerar tokens.</p>
<h3 id="heading-passo-5-proteger-rotas-da-api">Passo 5 – Proteger rotas da API</h3>
<p>Em <code>routes/api.php</code>:</p>
<pre><code class="lang-php">Route::middleware(<span class="hljs-string">'auth:sanctum'</span>)-&gt;get(<span class="hljs-string">'/user'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Request $request</span>) </span>{
    <span class="hljs-keyword">return</span> $request-&gt;user();
});
</code></pre>
<p>Agora essa rota só pode ser acessada por usuários autenticados via Sanctum.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768416447243/5fde7137-4f0f-45ff-af7e-9f84f4ad4d2e.jpeg" alt class="image--center mx-auto" /></a></p>
<h2 id="heading-conclusao">Conclusão</h2>
<p>O Laravel Sanctum é uma solução poderosa e simples para autenticação moderna em APIs e SPAs. Ele elimina complexidades desnecessárias e cobre a maioria dos casos reais de mercado.</p>
<p>Se você precisa:</p>
<ul>
<li><p>Proteger APIs</p>
</li>
<li><p>Integrar com frontend moderno</p>
</li>
<li><p>Trabalhar com tokens de forma segura</p>
</li>
</ul>
<p>👉 <strong>O Sanctum é a escolha certa.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Requests e Validação]]></title><description><![CDATA[https://www.youtube.com/watch?v=brAIASlkj7w
 
Introdução
Ao construir uma aplicação web, é fundamental validar os dados que são submetidos pelos usuários. O Laravel oferece uma maneira fácil e eficaz de lidar com validação de dados através de Request...]]></description><link>https://areadev.com.br/requests-e-validacao</link><guid isPermaLink="true">https://areadev.com.br/requests-e-validacao</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Tue, 11 Jun 2024 03:00:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717781593062/19c851f4-e964-4733-8ae3-68a83181ed67.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=brAIASlkj7w">https://www.youtube.com/watch?v=brAIASlkj7w</a></div>
<p> </p>
<h4 id="heading-introducao">Introdução</h4>
<p>Ao construir uma aplicação web, é fundamental validar os dados que são submetidos pelos usuários. O Laravel oferece uma maneira fácil e eficaz de lidar com validação de dados através de Requests e de recursos integrados para validação.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768417689084/0d93df31-1868-4e62-b3e8-25df344bb4a8.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-criando-requests">Criando Requests</h4>
<p>Requests são classes que encapsulam a lógica de validação de dados de entrada. Elas são usadas para validar os dados que são submetidos através de formulários HTTP.</p>
<h5 id="heading-criando-um-request">Criando um Request</h5>
<p>Você pode criar uma nova classe de Request usando o Artisan CLI:</p>
<pre><code class="lang-bash">php artisan make:request StorePostRequest
</code></pre>
<p>Isso criará um arquivo de Request em <code>app/Http/Requests</code>.</p>
<h5 id="heading-definindo-regras-de-validacao">Definindo Regras de Validação</h5>
<p>Dentro da classe de Request, você pode definir as regras de validação no método <code>rules</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'required|string|max:255'</span>,
            <span class="hljs-string">'body'</span> =&gt; <span class="hljs-string">'required|string'</span>,
        ];
    }</span>
</code></pre>
<h5 id="heading-usando-o-request">Usando o Request</h5>
<p>Para usar o Request em um controlador, basta injetá-lo no método desejado:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Requests</span>\<span class="hljs-title">StorePostRequest</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">store</span>(<span class="hljs-params">StorePostRequest $request</span>)
    </span>{
        <span class="hljs-comment">// Se chegar até aqui, os dados são válidos</span>
        <span class="hljs-comment">// Lógica para salvar o post</span>
    }</span>
</code></pre>
<h4 id="heading-exibindo-mensagens-de-erro">Exibindo Mensagens de Erro</h4>
<p>O Laravel fornece recursos para exibir mensagens de erro personalizadas quando a validação falha.</p>
<h5 id="heading-exibindo-erros-na-view">Exibindo Erros na View</h5>
<p>Você pode exibir mensagens de erro diretamente na view usando a função <code>@error</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    &lt;input type=<span class="hljs-string">"text"</span> name=<span class="hljs-string">"title"</span> value=<span class="hljs-string">"{{ old('title') }}"</span>&gt;
    @<span class="hljs-built_in">error</span>(<span class="hljs-string">'title'</span>)
        &lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">alert</span> <span class="hljs-title">alert</span>-<span class="hljs-title">danger</span>"&gt;</span>{{ $message }}&lt;/div&gt;
    @enderror</span>
</code></pre>
<h5 id="heading-redirecionando-com-mensagens-de-erro">Redirecionando com Mensagens de Erro</h5>
<p>Ao redirecionar de volta ao formulário com mensagens de erro, você pode usar o método <code>withErrors</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/form'</span>)
        -&gt;withErrors($validator)
        -&gt;withInput();</span>
</code></pre>
<h4 id="heading-validacao-em-controller">Validação em Controller</h4>
<p>Você também pode validar dados diretamente nos métodos dos controladores, sem a necessidade de criar uma classe de Request separada.</p>
<h5 id="heading-validacao-no-controller">Validação no Controller</h5>
<p>Você pode validar os dados diretamente no método do controlador usando o facade <code>Validator</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
  <span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Validator</span>;

  <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">store</span>(<span class="hljs-params">Request $request</span>)
  </span>{
        $validator = Validator::make($request-&gt;all(), [
            <span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'required|string|max:255'</span>,
            <span class="hljs-string">'body'</span> =&gt; <span class="hljs-string">'required|string'</span>,
        ]);

        <span class="hljs-keyword">if</span> ($validator-&gt;fails()) {
            <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/form'</span>)
                -&gt;withErrors($validator)
                -&gt;withInput();
        }

        <span class="hljs-comment">// Lógica para salvar o post</span>
   }</span>
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768417750677/45b1a5d4-75cd-4b1c-9b4f-555f4d7392a5.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Requests e Validação são partes essenciais do processo de desenvolvimento de uma aplicação web segura e funcional. O Laravel oferece uma maneira fácil e eficiente de validar os dados de entrada dos usuários, garantindo que apenas dados válidos sejam aceitos e processados pela aplicação. Ao utilizar Requests e as funcionalidades integradas de validação do Laravel, você pode construir uma aplicação robusta e confiável que oferece uma experiência de usuário consistente e livre de erros. Nos próximos tópicos, continuaremos explorando as poderosas ferramentas e recursos do Laravel para construir aplicações web incríveis.</p>
]]></content:encoded></item><item><title><![CDATA[Autorização com Policies]]></title><description><![CDATA[Como utilizar Policies no Laravel para garantir que apenas usuários autorizados acessem seus recursos
https://www.youtube.com/watch?v=8l7IRN13JNM
 
Proteja sua Aplicação com Autorizações
Criando Políticas
Políticas são classes que organizam a lógica ...]]></description><link>https://areadev.com.br/autorizacao-com-policies</link><guid isPermaLink="true">https://areadev.com.br/autorizacao-com-policies</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Tue, 11 Jun 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721883594497/bc9eef1b-71eb-4448-9802-2f4e3ac61559.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-como-utilizar-policies-no-laravel-para-garantir-que-apenas-usuarios-autorizados-acessem-seus-recursos">Como utilizar Policies no Laravel para garantir que apenas usuários autorizados acessem seus recursos</h3>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=8l7IRN13JNM">https://www.youtube.com/watch?v=8l7IRN13JNM</a></div>
<p> </p>
<p>Proteja sua Aplicação com Autorizações</p>
<h3 id="heading-criando-politicas">Criando Políticas</h3>
<p>Políticas são classes que organizam a lógica de autorização em torno de um modelo ou recurso específico. Por exemplo, se seu aplicativo for um blog, você poderá ter um modelo <code>App\Models\Post</code> e um <code>App\Policies\PostPolicy</code> correspondente para autorizar ações do usuário, como criar ou atualizar postagens.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768485120076/5b84b166-0193-45ba-9eaf-0c2dbe9dc30e.jpeg" alt class="image--center mx-auto" /></a></p>
<p>Você pode gerar uma política usando o comando <code>make:policy</code> Artisan. A política gerada será colocada no diretório <code>app/Policies</code>. Se este diretório não existir em sua aplicação, o Laravel irá criá-lo para você:</p>
<pre><code class="lang-php">sail artisan make:policy PostPolicy
</code></pre>
<p>O comando make:policy irá gerar uma classe de política vazia. Se você quiser gerar uma classe com exemplos de métodos de política relacionados à visualização, criação, atualização e exclusão do recurso, você pode fornecer uma opção --model ao executar o comando:</p>
<pre><code class="lang-php">sail artisan make:policy PostPolicy --model=Post
</code></pre>
<h3 id="heading-registrando-politicas">Registrando Políticas</h3>
<p>Depois que a classe de política for criada, ela precisará ser registrada.<br />Registrar políticas é como podemos informar ao Laravel qual política usar ao autorizar ações contra um determinado tipo de modelo.</p>
<p>O <code>App\Providers\AuthServiceProvider</code> incluído nas novas aplicações Laravel contém uma propriedade de políticas que mapeia seus modelos Eloquent para suas políticas correspondentes. Registrar uma política instruirá o Laravel qual política utilizar ao autorizar ações contra um determinado modelo do Eloquent:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Providers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Policies</span>\<span class="hljs-title">PostPolicy</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Foundation</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Providers</span>\<span class="hljs-title">AuthServiceProvider</span> <span class="hljs-title">as</span> <span class="hljs-title">ServiceProvider</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AuthServiceProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ServiceProvider</span>
</span>{
    <span class="hljs-comment">/**
     * The policy mappings for the application.
     *
     * <span class="hljs-doctag">@var</span> array
     */</span>
    <span class="hljs-keyword">protected</span> $policies = [
        Post::class =&gt; PostPolicy::class,
    ];

    <span class="hljs-comment">/**
     * Register any application authentication / authorization services.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boot</span>(<span class="hljs-params"></span>): <span class="hljs-title">void</span>
    </span>{
        <span class="hljs-comment">// ...</span>
    }
}
</code></pre>
<h3 id="heading-escrevendo-politicas">Escrevendo Políticas</h3>
<p>Métodos de política</p>
<p>Depois que a classe de política for registrada, você poderá adicionar métodos para cada ação que ela autorizar. Por exemplo, vamos definir um método de atualização em nossa PostPolicy que determina se um determinado App\Models\User pode atualizar uma determinada instância de App\Models\Post.</p>
<p>O método update receberá uma instância User e uma Post como argumentos e deverá retornar verdadeiro ou falso indicando se o usuário está autorizado a atualizar o Post fornecido. Portanto, neste exemplo, verificaremos se o id do usuário corresponde ao user_id da postagem:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Policies</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostPolicy</span>
</span>{
    <span class="hljs-comment">/**
     * Determine if the given post can be updated by the user.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">User $user, Post $post</span>): <span class="hljs-title">bool</span>
    </span>{
        <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id;
    }
}
</code></pre>
<p>Você pode continuar a definir métodos adicionais na política conforme necessário para as diversas ações que ela autoriza. Por exemplo, você pode definir métodos de visualização ou exclusão para autorizar várias ações relacionadas à postagem, mas lembre-se de que você é livre para dar aos seus métodos de política o nome que desejar.</p>
<p>Se você usou a opção --model ao gerar sua política por meio do console Artisan, ela já conterá métodos para as ações viewAny, view, create, update, delete, restore e forceDelete.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Todas as políticas são resolvidas através do contêiner de serviço Laravel, permitindo que você digite quaisquer dependências necessárias no construtor da política para que sejam injetadas automaticamente.</div>
</div>

<h3 id="heading-policy-responses">Policy Responses</h3>
<p>Até agora, examinamos apenas métodos de política que retornam valores booleanos simples. No entanto, às vezes você pode desejar retornar uma resposta mais detalhada, incluindo uma mensagem de erro. Para fazer isso, você pode retornar uma instância Illuminate\Auth\Access\Response do seu método de política:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Auth</span>\<span class="hljs-title">Access</span>\<span class="hljs-title">Response</span>;

<span class="hljs-comment">/**
 * Determine if the given post can be updated by the user.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">User $user, Post $post</span>): <span class="hljs-title">Response</span>
</span>{
    <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id
                ? Response::allow()
                : Response::deny(<span class="hljs-string">'You do not own this post.'</span>);
}
</code></pre>
<p>Ao retornar uma resposta de autorização da sua política, o método Gate::allows ainda retornará um valor booleano simples; entretanto, você pode usar o método Gate::inspect para obter a resposta de autorização completa retornada pelo portão:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

$response = Gate::inspect(<span class="hljs-string">'update'</span>, $post);

<span class="hljs-keyword">if</span> ($response-&gt;allowed()) {
    <span class="hljs-comment">// The action is authorized...</span>
} <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">echo</span> $response-&gt;message();
}
</code></pre>
<p>Ao usar o método Gate::authorize, que lança uma AuthorizationException se a ação não for autorizada, a mensagem de erro fornecida pela resposta de autorização será propagada para a resposta HTTP:</p>
<pre><code class="lang-php">Gate::authorize(<span class="hljs-string">'update'</span>, $post);

<span class="hljs-comment">// The action is authorized...</span>
</code></pre>
<h3 id="heading-personalizando-o-status-da-resposta-http">Personalizando o status da resposta HTTP</h3>
<p>Quando uma ação é negada por meio de um método de política, uma resposta HTTP 403 é retornada; entretanto, às vezes pode ser útil retornar um código de status HTTP alternativo. Você pode personalizar o código de status HTTP retornado para uma verificação de autorização com falha usando o construtor estático denyWithStatus na classe Illuminate\Auth\Access\Response:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Auth</span>\<span class="hljs-title">Access</span>\<span class="hljs-title">Response</span>;

<span class="hljs-comment">/**
 * Determine if the given post can be updated by the user.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">User $user, Post $post</span>): <span class="hljs-title">Response</span>
</span>{
    <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id
                ? Response::allow()
                : Response::denyWithStatus(<span class="hljs-number">404</span>);
}
</code></pre>
<p>Como ocultar recursos por meio de uma resposta 404 é um padrão comum para aplicações web, o método denyAsNotFound é oferecido por conveniência:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Auth</span>\<span class="hljs-title">Access</span>\<span class="hljs-title">Response</span>;

<span class="hljs-comment">/**
 * Determine if the given post can be updated by the user.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">User $user, Post $post</span>): <span class="hljs-title">Response</span>
</span>{
    <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id
                ? Response::allow()
                : Response::denyAsNotFound();
}
</code></pre>
<h3 id="heading-metodos-sem-modelos">Métodos sem modelos</h3>
<p>Alguns métodos de política recebem apenas uma instância do usuário atualmente autenticado. Esta situação é mais comum ao autorizar ações de criação. Por exemplo, se você estiver criando um blog, talvez queira determinar se um usuário está autorizado a criar postagens. Nessas situações, seu método de política deverá esperar receber apenas uma instância de usuário:</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * Determine if the given user can create posts.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">create</span>(<span class="hljs-params">User $user</span>): <span class="hljs-title">bool</span>
</span>{
    <span class="hljs-keyword">return</span> $user-&gt;role == <span class="hljs-string">'writer'</span>;
}
</code></pre>
<h3 id="heading-usuarios-convidados">Usuários convidados</h3>
<p>Por padrão, todos os gates e políticas retornam automaticamente falso se a solicitação HTTP recebida não tiver sido iniciada por um usuário autenticado.</p>
<p>No entanto, você pode permitir que essas verificações de autorização passem para seus gates e policies declarando uma dica de tipo "opcional" ou fornecendo um valor padrão nulo para a definição do argumento do usuário:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Policies</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostPolicy</span>
</span>{
    <span class="hljs-comment">/**
     * Determine if the given post can be updated by the user.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">?User $user, Post $post</span>): <span class="hljs-title">bool</span>
    </span>{
        <span class="hljs-keyword">return</span> $user?-&gt;id === $post-&gt;user_id;
    }
}
</code></pre>
<h3 id="heading-filtros-de-politica">Filtros de política</h3>
<p>Para determinados usuários, você pode autorizar todas as ações dentro de uma determinada política. Para fazer isso, defina um método before na política.<br />O método before será executado antes de qualquer outro método na política, dando a você a oportunidade de autorizar a ação antes que o método de política pretendido seja realmente chamado. Este recurso é mais comumente usado para autorizar administradores de aplicativos a executar qualquer ação:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;

<span class="hljs-comment">/**
 * Perform pre-authorization checks.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">before</span>(<span class="hljs-params">User $user, <span class="hljs-keyword">string</span> $ability</span>): <span class="hljs-title">bool</span>|<span class="hljs-title">null</span>
</span>{
    <span class="hljs-keyword">if</span> ($user-&gt;isAdministrator()) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
</code></pre>
<p>Se desejar negar todas as verificações de autorização para um tipo específico de usuário, você poderá retornar false do método before. Se null for retornado, a verificação de autorização passará para o método de política.</p>
<p>O método before de uma classe de política não será chamado se a classe não contiver um método com um nome correspondente ao nome da habilidade que está sendo verificada.</p>
<h3 id="heading-autorizando-acoes-usando-politicas">Autorizando ações usando políticas</h3>
<p>Através do modelo de usuário</p>
<p>O modelo App\Models\User incluído em sua aplicação Laravel inclui dois métodos úteis para autorizar ações: <code>can</code> e <code>cannot</code>. Os métodos <code>can</code> e <code>cannot</code> não recebem o nome da ação que você deseja autorizar e o modelo relevante. Por exemplo, vamos determinar se um usuário está autorizado a atualizar um determinado modelo App\Models\Post. Normalmente, isso será feito dentro de um método de controlador:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-comment">/**
     * Update the given post.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">Request $request, Post $post</span>): <span class="hljs-title">RedirectResponse</span>
    </span>{
        <span class="hljs-keyword">if</span> ($request-&gt;user()-&gt;cannot(<span class="hljs-string">'update'</span>, $post)) {
            abort(<span class="hljs-number">403</span>);
        }

        <span class="hljs-comment">// Update the post...</span>

        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);
    }
}
</code></pre>
<p>Se uma política for registrada para um determinado modelo, o método can chamará automaticamente a política apropriada e retornará o resultado booleano. Se nenhuma política for registrada para o modelo, o método can tentará chamar o Gate baseado em fechamento correspondente ao nome da ação fornecido.</p>
<p><strong>Ações que não requerem modelos</strong></p>
<p>Lembre-se, algumas ações podem corresponder a métodos de política como create que não requerem uma instância de modelo. Nessas situações, você pode passar um nome de classe para o método can. O nome da classe será usado para determinar qual política usar ao autorizar a ação:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-comment">/**
     * Create a post.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">store</span>(<span class="hljs-params">Request $request</span>): <span class="hljs-title">RedirectResponse</span>
    </span>{
        <span class="hljs-keyword">if</span> ($request-&gt;user()-&gt;cannot(<span class="hljs-string">'create'</span>, Post::class)) {
            abort(<span class="hljs-number">403</span>);
        }

        <span class="hljs-comment">// Create the post...</span>

        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);
    }
}
</code></pre>
<h3 id="heading-via-controller-helpers">Via Controller Helpers</h3>
<p>Além dos métodos úteis fornecidos para o modelo App\Models\User, o Laravel fornece um método de autorização útil para qualquer um dos seus controladores que estendem a classe base App\Http\Controllers\Controller.</p>
<p>Assim como o método can, este método aceita o nome da ação que você deseja autorizar e o modelo relevante. Se a ação não for autorizada, o método authorize lançará uma exceção Illuminate\Auth\Access\AuthorizationException que o manipulador de exceção do Laravel converterá automaticamente em uma resposta HTTP com um código de status 403:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-comment">/**
     * Update the given blog post.
     *
     * <span class="hljs-doctag">@throws</span> \Illuminate\Auth\Access\AuthorizationException
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">Request $request, Post $post</span>): <span class="hljs-title">RedirectResponse</span>
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;authorize(<span class="hljs-string">'update'</span>, $post);

        <span class="hljs-comment">// The current user can update the blog post...</span>

        <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);
    }
}
</code></pre>
<p>Ações que não requerem modelos</p>
<p>Conforme discutido anteriormente, alguns métodos de política como create não requerem uma instância de modelo. Nessas situações, você deve passar um nome de classe para o método de autorização. O nome da classe será usado para determinar qual política usar ao autorizar a ação:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;

<span class="hljs-comment">/**
 * Create a new blog post.
 *
 * <span class="hljs-doctag">@throws</span> \Illuminate\Auth\Access\AuthorizationException
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">create</span>(<span class="hljs-params">Request $request</span>): <span class="hljs-title">RedirectResponse</span>
</span>{
    <span class="hljs-keyword">$this</span>-&gt;authorize(<span class="hljs-string">'create'</span>, Post::class);

    <span class="hljs-comment">// The current user can create blog posts...</span>

    <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);
}
</code></pre>
<p>Autorizando Controladores de Recursos</p>
<p>Se você estiver utilizando controladores de recursos, poderá usar o método authorizeResource no construtor do seu controlador. Este método anexará as definições de middleware apropriadas aos métodos do controlador de recursos.</p>
<p>O método authorizeResource aceita o nome da classe do modelo como seu primeiro argumento, e o nome do parâmetro de rota/solicitação que conterá o ID do modelo como seu segundo argumento. Você deve garantir que seu controlador de recursos seja criado usando o sinalizador --model para que ele tenha as assinaturas de método e dicas de tipo necessárias:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-comment">/**
     * Create the controller instance.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;authorizeResource(Post::class, <span class="hljs-string">'post'</span>);
    }
}
</code></pre>
<p>Os seguintes métodos de controlador serão mapeados para seu método de política correspondente. Quando as solicitações são roteadas para um determinado método do controlador, o método de política correspondente será automaticamente invocado antes que o método do controlador seja executado:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Controller Method</td><td>Policy Method</td></tr>
</thead>
<tbody>
<tr>
<td>index</td><td>viewAny</td></tr>
<tr>
<td>show</td><td>view</td></tr>
<tr>
<td>create</td><td>create</td></tr>
<tr>
<td>store</td><td>create</td></tr>
<tr>
<td>edit</td><td>update</td></tr>
<tr>
<td>update</td><td>update</td></tr>
<tr>
<td>destroy</td><td>delete</td></tr>
</tbody>
</table>
</div><p>Você pode usar o comando make:policy com a opção --model para gerar rapidamente uma classe de política para um determinado modelo:</p>
<pre><code class="lang-php">sail artesão make:policy PostPolicy --model=Post
</code></pre>
<h3 id="heading-atraves-de-middleware">Através de Middleware</h3>
<p>O Laravel inclui um middleware que pode autorizar ações antes mesmo que a solicitação recebida chegue às suas rotas ou controladores. Por padrão, o middleware <code>Illuminate\Auth\Middleware\Authorize</code> recebe a chave can em sua classe <code>App\Http\Kernel</code> Vamos explorar um exemplo de uso do middleware can para autorizar que um usuário possa atualizar uma postagem:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;

Route::put(<span class="hljs-string">'/post/{post}'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Post $post</span>) </span>{
    <span class="hljs-comment">// The current user may update the post...</span>
})-&gt;middleware(<span class="hljs-string">'can:update,post'</span>);
</code></pre>
<p>Neste exemplo, estamos passando dois argumentos ao middleware can. O primeiro é o nome da ação que desejamos autorizar e o segundo é o parâmetro de rota que desejamos passar para o método de política. Nesse caso, como estamos usando vinculação de modelo implícita, um modelo <code>App\Models\Post</code> será passado para o método de política. Caso o usuário não esteja autorizado a realizar a ação determinada, uma resposta HTTP com código de status 403 será retornada pelo middleware.</p>
<p>Por conveniência, você também pode anexar o middleware can à sua rota usando o método can:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;

Route::put(<span class="hljs-string">'/post/{post}'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Post $post</span>) </span>{
    <span class="hljs-comment">// The current user may update the post...</span>
})-&gt;can(<span class="hljs-string">'update'</span>, <span class="hljs-string">'post'</span>);
</code></pre>
<p>Ações que não requerem modelos</p>
<p>Novamente, alguns métodos de política como create não requerem uma instância de modelo. Nessas situações, você pode passar um nome de classe para o middleware. O nome da classe será usado para determinar qual política usar ao autorizar a ação:</p>
<pre><code class="lang-php">Route::post(<span class="hljs-string">'/post'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// The current user may create posts...</span>
})-&gt;middleware(<span class="hljs-string">'can:create,App\Models\Post'</span>);
</code></pre>
<p>Especificar o nome inteiro da classe em uma definição de middleware de string pode se tornar complicado. Por esse motivo, você pode optar por anexar o middleware can à sua rota usando o método can:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;

Route::post(<span class="hljs-string">'/post'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// The current user may create posts...</span>
})-&gt;can(<span class="hljs-string">'create'</span>, Post::class);
</code></pre>
<h3 id="heading-via-blade-templates">Via Blade Templates</h3>
<p>Ao escrever modelos Blade, você pode desejar exibir uma parte da página somente se o usuário estiver autorizado a executar uma determinada ação. Por exemplo, você pode querer mostrar um formulário de atualização para uma postagem de blog apenas se o usuário puder realmente atualizar a postagem. Nesta situação, você pode usar as diretivas <code>@can</code> e <code>@cannot</code>:</p>
<pre><code class="lang-php">@can(<span class="hljs-string">'update'</span>, $post)
    &lt;!-- The current user can update the post... --&gt;
@elsecan(<span class="hljs-string">'create'</span>, App\Models\Post::class)
    &lt;!-- The current user can create <span class="hljs-keyword">new</span> posts... --&gt;
@<span class="hljs-keyword">else</span>
    &lt;!-- ... --&gt;
@endcan

@cannot(<span class="hljs-string">'update'</span>, $post)
    &lt;!-- The current user cannot update the post... --&gt;
@elsecannot(<span class="hljs-string">'create'</span>, App\Models\Post::class)
    &lt;!-- The current user cannot create <span class="hljs-keyword">new</span> posts... --&gt;
@endcannot
</code></pre>
<p>Essas diretivas são atalhos convenientes para escrever instruções <code>@if</code> e <code>@unless</code>. As declarações <code>@can</code> e <code>@cannot</code> acima são equivalentes às seguintes declarações:</p>
<pre><code class="lang-php">@<span class="hljs-keyword">if</span> (Auth::user()-&gt;can(<span class="hljs-string">'update'</span>, $post))
    &lt;!-- The current user can update the post... --&gt;
@<span class="hljs-keyword">endif</span>

@unless (Auth::user()-&gt;can(<span class="hljs-string">'update'</span>, $post))
    &lt;!-- The current user cannot update the post... --&gt;
@endunless
</code></pre>
<p>Você também pode determinar se um usuário está autorizado a executar qualquer ação de um determinado conjunto de ações. Para fazer isso, use a diretiva <code>@canany</code>:</p>
<pre><code class="lang-php">@canany([<span class="hljs-string">'update'</span>, <span class="hljs-string">'view'</span>, <span class="hljs-string">'delete'</span>], $post)
    &lt;!-- The current user can update, view, <span class="hljs-keyword">or</span> delete the post... --&gt;
@elsecanany([<span class="hljs-string">'create'</span>], \App\Models\Post::class)
    &lt;!-- The current user can create a post... --&gt;
@endcanany
</code></pre>
<p>Ações que não requerem modelos</p>
<p>Como a maioria dos outros métodos de autorização, você pode passar um nome de classe para as diretivas <code>@can</code> e <code>@cannot</code> se a ação não exigir uma instância de modelo:</p>
<pre><code class="lang-php">@can(<span class="hljs-string">'create'</span>, App\Models\Post::class)
    &lt;!-- The current user can create posts... --&gt;
@endcan

@cannot(<span class="hljs-string">'create'</span>, App\Models\Post::class)
    &lt;!-- The current user can<span class="hljs-string">'t create posts... --&gt;
@endcannot</span>
</code></pre>
<p>Fornecendo Contexto Adicional</p>
<p>Ao autorizar ações usando políticas, você pode passar um array como segundo argumento para as diversas funções de autorização e auxiliares. O primeiro elemento da matriz será usado para determinar qual política deve ser invocada, enquanto o restante dos elementos da matriz são passados ​​como parâmetros para o método de política e podem ser usados ​​para contexto adicional ao tomar decisões de autorização. Por exemplo, considere a seguinte definição de método PostPolicy que contém um parâmetro $category adicional:</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * Determine if the given post can be updated by the user.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">User $user, Post $post, <span class="hljs-keyword">int</span> $category</span>): <span class="hljs-title">bool</span>
</span>{
    <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id &amp;&amp;
           $user-&gt;canUpdateCategory($category);
}
</code></pre>
<p>Ao tentar determinar se o usuário autenticado pode atualizar uma determinada postagem, podemos invocar este método de política da seguinte forma:</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * Update the given blog post.
 *
 * <span class="hljs-doctag">@throws</span> \Illuminate\Auth\Access\AuthorizationException
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">Request $request, Post $post</span>): <span class="hljs-title">RedirectResponse</span>
</span>{
    <span class="hljs-keyword">$this</span>-&gt;authorize(<span class="hljs-string">'update'</span>, [$post, $request-&gt;category]);

    <span class="hljs-comment">// The current user can update the blog post...</span>

    <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);
}
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768485139497/b980da86-92ae-45ae-ac57-b00d2b744ac6.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Implementar autenticação e autorização no Laravel é uma tarefa simplificada graças às ferramentas e funcionalidades integradas do framework. Com o sistema de autenticação básico e proteção de rotas com middleware, você pode garantir que sua aplicação esteja segura e que os usuários tenham acesso apropriado às diferentes partes do sistema. Nos próximos tópicos, exploraremos outras funcionalidades do Laravel para continuar aprimorando suas habilidades no desenvolvimento de aplicações robustas e eficientes.</p>
]]></content:encoded></item><item><title><![CDATA[Autorização com Gates]]></title><description><![CDATA[https://www.youtube.com/watch?v=bz7W_NbGkzE
 

Requisitos
Código das Migrations:
Schema::create('posts', function (Blueprint $table) {
   $table->id();
   $table->foreignId('user_id')->constrained()->onDelete('cascade');
   $table->string('title');
 ...]]></description><link>https://areadev.com.br/autenticacao-e-autorizacao</link><guid isPermaLink="true">https://areadev.com.br/autenticacao-e-autorizacao</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Mon, 10 Jun 2024 03:00:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721883476533/ff24435f-e770-41ce-b1b0-cde2ab535d7a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=bz7W_NbGkzE">https://www.youtube.com/watch?v=bz7W_NbGkzE</a></div>
<p> </p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768486414055/8d900b54-08b4-4a09-9ba2-3b8f086ab78e.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-requisitos">Requisitos</h3>
<p>Código das Migrations:</p>
<pre><code class="lang-php">Schema::create(<span class="hljs-string">'posts'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
   $table-&gt;id();
   $table-&gt;foreignId(<span class="hljs-string">'user_id'</span>)-&gt;constrained()-&gt;onDelete(<span class="hljs-string">'cascade'</span>);
   $table-&gt;string(<span class="hljs-string">'title'</span>);
   $table-&gt;text(<span class="hljs-string">'content'</span>);
   $table-&gt;timestamps();
});
</code></pre>
<p>Execute:</p>
<pre><code class="lang-php">sail artisan migrate
</code></pre>
<p>Banco de dados</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721969038293/bd3fdcea-8034-4213-a14b-6bd6ef355f41.png" alt class="image--center mx-auto" /></p>
<p>Seeder</p>
<pre><code class="lang-php">sail artisan make:seeder UsersTableSeeder
sail artisan make:seeder PostsTableSeeder
</code></pre>
<p>UsersTableSeeder</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">DB</span>;

DB::table(<span class="hljs-string">'users'</span>)-&gt;insert([
    [
      <span class="hljs-string">'name'</span> =&gt; <span class="hljs-string">'areadev'</span>,
      <span class="hljs-string">'email'</span> =&gt; <span class="hljs-string">'areadev@gmail.com'</span>,
      <span class="hljs-string">'password'</span> =&gt; Hash::make(<span class="hljs-string">'12341234'</span>),
    ],
    [
      <span class="hljs-string">'name'</span> =&gt; <span class="hljs-string">'bruno'</span>,
      <span class="hljs-string">'email'</span> =&gt; <span class="hljs-string">'bruno@gmail.com'</span>,
      <span class="hljs-string">'password'</span> =&gt; Hash::make(<span class="hljs-string">'12341234'</span>),
     ],
]);
</code></pre>
<p>PostsTableSeeder</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">DB</span>;

<span class="hljs-comment">// Obter o ID dos usuários</span>
$userIds = DB::table(<span class="hljs-string">'users'</span>)-&gt;pluck(<span class="hljs-string">'id'</span>);

<span class="hljs-comment">// Criar posts para cada usuário</span>
<span class="hljs-keyword">foreach</span> ($userIds <span class="hljs-keyword">as</span> $userId) {
   DB::table(<span class="hljs-string">'posts'</span>)-&gt;insert([
    [
      <span class="hljs-string">'user_id'</span> =&gt; $userId,
      <span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'Post Title '</span> . $userId . <span class="hljs-string">' - 1'</span>,
      <span class="hljs-string">'content'</span> =&gt; <span class="hljs-string">'This is the content for post 1 of user '</span> . $userId,
    ],
    [
      <span class="hljs-string">'user_id'</span> =&gt; $userId,
      <span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'Post Title '</span> . $userId . <span class="hljs-string">' - 2'</span>,
      <span class="hljs-string">'content'</span> =&gt; <span class="hljs-string">'This is the content for post 2 of user '</span> . $userId,
     ],
    ]);
}
</code></pre>
<p>DatabaseSeeder</p>
<pre><code class="lang-php"><span class="hljs-keyword">$this</span>-&gt;call([
  FruitsTableSeeder::class,
  UsersTableSeeder::class,
  PostsTableSeeder::class,
]);
</code></pre>
<p>Model User</p>
<pre><code class="lang-php"><span class="hljs-comment">/* adicione o seguinte código no final do arquivo. */</span>

<span class="hljs-comment">/**
 * Get the posts for the user.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">posts</span>(<span class="hljs-params"></span>)
</span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;hasMany(Post::class);
}
</code></pre>
<p>Model Post</p>
<pre><code class="lang-php"><span class="hljs-keyword">protected</span> $fillable = [
    <span class="hljs-string">'user_id'</span>,
    <span class="hljs-string">'title'</span>,
    <span class="hljs-string">'content'</span>,
];

<span class="hljs-comment">/**
 * Get the user that owns the post.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">user</span>(<span class="hljs-params"></span>)
</span>{
   <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;belongsTo(User::class);
}
</code></pre>
<hr />
<h3 id="heading-objetivo">Objetivo</h3>
<p>Implementar sistemas de autenticação e autorização para proteger e gerenciar o acesso à aplicação é crucial para qualquer aplicação web. No Laravel, essas funcionalidades são integradas de maneira eficiente e segura, permitindo que você configure e gerencie o acesso dos usuários com facilidade.</p>
<h3 id="heading-authorization">Authorization</h3>
<p>Além de fornecer serviços de autenticação integrados, o Laravel também fornece uma maneira simples de autorizar ações do usuário em um determinado recurso.</p>
<p>Por exemplo, mesmo que um usuário seja autenticado, ele pode não estar autorizado a atualizar ou excluir determinados modelos do Eloquent ou registros de banco de dados gerenciados pela sua aplicação. Os recursos de autorização do Laravel fornecem uma maneira fácil e organizada de gerenciar esses tipos de verificações de autorização.</p>
<p>O Laravel fornece duas formas principais de autorizar ações: gates e policies.<br />Pense em gates e policies como rotas e controladores.</p>
<p>Gates fornece uma abordagem simples e baseada em fechamento para autorização, enquanto políticas, como controladores, agrupam lógica em torno de um modelo ou recurso específico.</p>
<p>Você não precisa escolher entre usar exclusivamente gates ou usar exclusivamente policies ao criar um aplicativo. A maioria dos aplicativos provavelmente conterá alguma mistura de gates e policies, e isso é perfeitamente normal!</p>
<p>Gates são mais aplicáveis ​​a ações que não estão relacionadas a nenhum modelo ou recurso, como visualizar um painel de administrador. Por outro lado, as políticas devem ser utilizadas quando se deseja autorizar uma ação para um modelo ou recurso específico.</p>
<h3 id="heading-gates">Gates</h3>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Gates são uma ótima maneira de aprender o básico dos recursos de autorização do Laravel; entretanto, ao construir aplicações Laravel robustas você deve considerar o uso de policies para organizar suas regras de autorização.</div>
</div>

<p>Gates são simplesmente fechamentos que determinam se um usuário está autorizado a realizar uma determinada ação. Normalmente, os gates são definidos no método de inicialização da classe <code>App\Providers\AuthServiceProvider</code> usando a facade Gate.</p>
<p>Gates sempre recebe uma instância de usuário como seu primeiro argumento e pode opcionalmente receber argumentos adicionais, como um modelo Eloquent relevante.</p>
<p>Neste exemplo, definiremos um gate para determinar se um usuário pode atualizar um determinado modelo <code>App\Models\Post</code>. O gate fará isso comparando o id do usuário com o user_id do usuário que criou a postagem:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">ServiceProvider</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppServiceProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ServiceProvider</span>
</span>{ 
    <span class="hljs-comment">/**
     * The policy mappings for the application.
     * As políticas são registradas em um array associativo.
     * Onde a chave é o modelo e o valor é a classe da política.
     * <span class="hljs-doctag">@var</span> array&lt;class-string, class-string&gt;
     */</span>
    <span class="hljs-keyword">protected</span> $policies = [
        <span class="hljs-comment">// 'App\Models\Model' =&gt; 'App\Policies\ModelPolicy',</span>
    ];


    <span class="hljs-comment">/**
     * Register any authentication / authorization services.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boot</span>(<span class="hljs-params"></span>): <span class="hljs-title">void</span>
    </span>{
       <span class="hljs-comment">/**
        * define um Gate, que é uma maneira de verificar se um usuário tem permissão para realizar uma ação específica.
        * A função anônima (closure) que você fornece define a lógica de autorização. Ela recebe dois parâmetros: um User e um Post.
        *
        * Parâmetros:
        *  User $user: O usuário que está tentando realizar a ação.
        *  Post $post: O modelo Post sobre o qual a ação está sendo realizada.
        */</span>
       Gate::define(<span class="hljs-string">'update-post'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">User $user, Post $post</span>) </span>{
         <span class="hljs-keyword">return</span> $user-&gt;id === $post-&gt;user_id;
        });
    }
}
</code></pre>
<p>Assim como os controladores, os gates também podem ser definidos usando um array de retorno de chamada de classe:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Policies</span>\<span class="hljs-title">PostPolicy</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

<span class="hljs-comment">/**
 * Register any authentication / authorization services.
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boot</span>(<span class="hljs-params"></span>): <span class="hljs-title">void</span>
</span>{
    Gate::define(<span class="hljs-string">'update-post'</span>, [PostPolicy::class, <span class="hljs-string">'update'</span>]);
}
</code></pre>
<h3 id="heading-autorizando-acoes">Autorizando Ações</h3>
<p>Para autorizar uma ação usando gates, você deve usar os métodos de permissão ou negação fornecidos pela facade Gate. Observe que você não é obrigado a passar o usuário atualmente autenticado para esses métodos. O Laravel cuidará automaticamente de passar o usuário para o fechamento do gate. É comum chamar os métodos de autorização de gate nos controladores da sua aplicação antes de executar uma ação que exija autorização:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span>(<span class="hljs-params"></span>)
    </span>{
         <span class="hljs-comment">// Busca todos os posts</span>
        $posts = Post::with(<span class="hljs-string">'user'</span>)-&gt;get();

        <span class="hljs-comment">// Retorna a view com os posts</span>
        <span class="hljs-keyword">return</span> view(<span class="hljs-string">'posts.index'</span>, compact(<span class="hljs-string">'posts'</span>));
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">edit</span>(<span class="hljs-params">Post $post</span>)
    </span>{
        <span class="hljs-comment">// Verifica se o usuário pode editar o post</span>
        <span class="hljs-comment">// allows - permite</span>
        <span class="hljs-keyword">if</span> (Gate::allows(<span class="hljs-string">'update-post'</span>, $post)) {
            <span class="hljs-keyword">return</span> view(<span class="hljs-string">'posts.edit'</span>, compact(<span class="hljs-string">'post'</span>));
        } <span class="hljs-keyword">else</span> {
            abort(<span class="hljs-number">403</span>, <span class="hljs-string">'Você não tem permissão para editar este post.'</span>);
        }
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span>(<span class="hljs-params">Request $request, Post $post</span>): <span class="hljs-title">RedirectResponse</span>
    </span>{
        <span class="hljs-comment">// Verifique se o usuário pode atualizar o post</span>
        <span class="hljs-keyword">if</span> (Gate::allows(<span class="hljs-string">'update-post'</span>, $post)) {

            <span class="hljs-comment">// Valida os dados</span>
            $validated = $request-&gt;validate([
                <span class="hljs-string">'title'</span> =&gt; <span class="hljs-string">'required|string|max:255'</span>,
                <span class="hljs-string">'content'</span> =&gt; <span class="hljs-string">'required|string'</span>,
            ]);

            <span class="hljs-comment">// Atualiza o post</span>
            $post-&gt;update($validated);

            <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);

        } <span class="hljs-keyword">else</span> {
            abort(<span class="hljs-number">403</span>, <span class="hljs-string">'Você não tem permissão para atualizar este post.'</span>);
        }
    }
}
</code></pre>
<p>Crie as views necessárias:</p>
<pre><code class="lang-php"><span class="hljs-comment">/* resources/views/posts/edit.blade.php */</span>
@<span class="hljs-keyword">extends</span>(<span class="hljs-string">'layouts.app'</span>)

@section(<span class="hljs-string">'content'</span>)
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">container</span>"&gt;
    &lt;<span class="hljs-title">h1</span>&gt;<span class="hljs-title">Editar</span> <span class="hljs-title">Post</span>&lt;/<span class="hljs-title">h1</span>&gt;

    @<span class="hljs-title">if</span> (<span class="hljs-title">session</span>('<span class="hljs-title">status</span>'))
        &lt;<span class="hljs-title">div</span> <span class="hljs-title">class</span>="<span class="hljs-title">alert</span> <span class="hljs-title">alert</span>-<span class="hljs-title">success</span>"&gt;
            </span>{{ session(<span class="hljs-string">'status'</span>) }}
        &lt;/div&gt;
    @<span class="hljs-keyword">endif</span>

    &lt;form action=<span class="hljs-string">"{{ route('post.update', <span class="hljs-subst">$post</span>) }}"</span> method=<span class="hljs-string">"POST"</span>&gt;
        @csrf
        @method(<span class="hljs-string">'PATCH'</span>)

        &lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">mb</span>-3"&gt;
            &lt;<span class="hljs-title">label</span> <span class="hljs-title">for</span>="<span class="hljs-title">title</span>" <span class="hljs-title">class</span>="<span class="hljs-title">form</span>-<span class="hljs-title">label</span>"&gt;<span class="hljs-title">T</span>í<span class="hljs-title">tulo</span>&lt;/<span class="hljs-title">label</span>&gt;
            &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">text</span>" <span class="hljs-title">class</span>="<span class="hljs-title">form</span>-<span class="hljs-title">control</span>" <span class="hljs-title">id</span>="<span class="hljs-title">title</span>" <span class="hljs-title">name</span>="<span class="hljs-title">title</span>" <span class="hljs-title">value</span>="</span>{{ old(<span class="hljs-string">'title'</span>, $post-&gt;title) }}<span class="hljs-string">" required&gt;
        &lt;/div&gt;

        &lt;div class="</span>mb<span class="hljs-number">-3</span><span class="hljs-string">"&gt;
            &lt;label for="</span>content<span class="hljs-string">" class="</span>form-label<span class="hljs-string">"&gt;Conteúdo&lt;/label&gt;
            &lt;textarea class="</span>form-control<span class="hljs-string">" id="</span>content<span class="hljs-string">" name="</span>content<span class="hljs-string">" rows="</span><span class="hljs-number">5</span><span class="hljs-string">" required&gt;{{ old('content', <span class="hljs-subst">$post</span>-&gt;content) }}&lt;/textarea&gt;
        &lt;/div&gt;

        &lt;button type="</span>submit<span class="hljs-string">" class="</span>btn btn-primary<span class="hljs-string">"&gt;Atualizar&lt;/button&gt;
    &lt;/form&gt;
&lt;/div&gt;
@endsection</span>
</code></pre>
<pre><code class="lang-php"><span class="hljs-comment">/* resources/views/posts/index.blade.php */</span>
@<span class="hljs-keyword">extends</span>(<span class="hljs-string">'layouts.app'</span>)

@section(<span class="hljs-string">'content'</span>)
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">container</span>"&gt;
    &lt;<span class="hljs-title">h1</span>&gt;<span class="hljs-title">Todos</span> <span class="hljs-title">os</span> <span class="hljs-title">Posts</span>&lt;/<span class="hljs-title">h1</span>&gt;

    &lt;<span class="hljs-title">table</span> <span class="hljs-title">class</span>="<span class="hljs-title">table</span>"&gt;
        &lt;<span class="hljs-title">thead</span>&gt;
            &lt;<span class="hljs-title">tr</span>&gt;
                &lt;<span class="hljs-title">th</span>&gt;<span class="hljs-title">T</span>í<span class="hljs-title">tulo</span>&lt;/<span class="hljs-title">th</span>&gt;
                &lt;<span class="hljs-title">th</span>&gt;<span class="hljs-title">Conte</span>ú<span class="hljs-title">do</span>&lt;/<span class="hljs-title">th</span>&gt;
                &lt;<span class="hljs-title">th</span>&gt;<span class="hljs-title">Autor</span>&lt;/<span class="hljs-title">th</span>&gt;
                &lt;<span class="hljs-title">th</span>&gt;<span class="hljs-title">A</span>çõ<span class="hljs-title">es</span>&lt;/<span class="hljs-title">th</span>&gt;
            &lt;/<span class="hljs-title">tr</span>&gt;
        &lt;/<span class="hljs-title">thead</span>&gt;
        &lt;<span class="hljs-title">tbody</span>&gt;
            @<span class="hljs-title">foreach</span> ($<span class="hljs-title">posts</span> <span class="hljs-title">as</span> $<span class="hljs-title">post</span>)
                &lt;<span class="hljs-title">tr</span>&gt;
                    &lt;<span class="hljs-title">td</span>&gt;</span>{{ $post-&gt;title }}&lt;/td&gt;
                    &lt;td&gt;{{ $post-&gt;content }}&lt;/td&gt;
                    &lt;td&gt;{{ $post-&gt;user-&gt;name }}&lt;/td&gt;
                    &lt;td&gt;
                        &lt;!-- Botão de edição --&gt;
                        &lt;a href=<span class="hljs-string">"{{ route('post.edit', <span class="hljs-subst">$post</span>) }}"</span> <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">btn</span> <span class="hljs-title">btn</span>-<span class="hljs-title">primary</span>"&gt;<span class="hljs-title">Editar</span>&lt;/<span class="hljs-title">a</span>&gt;

                        &lt;!-- <span class="hljs-title">Formul</span>á<span class="hljs-title">rio</span> <span class="hljs-title">de</span> <span class="hljs-title">exclus</span>ã<span class="hljs-title">o</span> --&gt;
                        &lt;<span class="hljs-title">form</span> <span class="hljs-title">action</span>="</span>{{ route(<span class="hljs-string">'post.delete'</span>, $post) }}<span class="hljs-string">" method="</span>POST<span class="hljs-string">" style="</span>display: inline;<span class="hljs-string">" onsubmit="</span><span class="hljs-keyword">return</span> confirm(<span class="hljs-string">'Tem certeza que deseja excluir este post?'</span>);<span class="hljs-string">"&gt;
                            @csrf
                            @method('DELETE')
                            &lt;button type="</span>submit<span class="hljs-string">" class="</span>btn btn-danger<span class="hljs-string">"&gt;Deletar&lt;/button&gt;
                        &lt;/form&gt;
                    &lt;/td&gt;
                &lt;/tr&gt;
            @endforeach
        &lt;/tbody&gt;
    &lt;/table&gt;

    @if (Auth::user()-&gt;can('view-users'))
        &lt;a href="</span>{{ url(<span class="hljs-string">'/users'</span>) }}<span class="hljs-string">"&gt;Lista de usuários&lt;/a&gt;
    @endif

&lt;/div&gt;
@endsection</span>
</code></pre>
<pre><code class="lang-php"><span class="hljs-comment">/* Rotas */</span>
Route::middleware(<span class="hljs-string">'auth'</span>)-&gt;group(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    Route::get(<span class="hljs-string">'/posts'</span>, [PostController::class, <span class="hljs-string">'index'</span>])-&gt;name(<span class="hljs-string">'posts.index'</span>);
    Route::get(<span class="hljs-string">'/post/{post}/edit'</span>, [PostController::class, <span class="hljs-string">'edit'</span>])-&gt;name(<span class="hljs-string">'post.edit'</span>);
    Route::patch(<span class="hljs-string">'/post/{post}'</span>, [PostController::class, <span class="hljs-string">'update'</span>])-&gt;name(<span class="hljs-string">'post.update'</span>);
    Route::delete(<span class="hljs-string">'/posts/{post}'</span>, [PostController::class, <span class="hljs-string">'destroy'</span>])-&gt;name(<span class="hljs-string">'post.delete'</span>);
});
</code></pre>
<p>Veja na imagem abaixo a rota posts!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148491826/99371e95-7a0d-40fb-bb07-0fe0c579b366.png" alt class="image--center mx-auto" /></p>
<p>Veja na imagem abaixo a rota para editar um post especifico!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721966902171/976fea5d-169a-4155-a633-5dc171e9d49e.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-autorizando-ou-lancando-excecoes">Autorizando ou lançando exceções</h3>
<p>Se você quiser tentar autorizar uma ação e lançar automaticamente uma Illuminate\Auth\Access\AuthorizationException se o usuário não tiver permissão para executar a ação dada, você pode usar o método de autorização da fachada Gate.</p>
<p>Instâncias de AuthorizationException são automaticamente convertidas em uma resposta HTTP 403 pelo manipulador de exceções do Laravel:</p>
<pre><code class="lang-php">Gate::authorize(<span class="hljs-string">'update-post'</span>, $post);

<span class="hljs-comment">// The action is authorized...</span>
</code></pre>
<p>Exemplo, no método destroy:</p>
<pre><code class="lang-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Post</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">RedirectResponse</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{

    <span class="hljs-comment">// outros métodos ...</span>

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">destroy</span>(<span class="hljs-params">Post $post</span>)
    </span>{
        <span class="hljs-comment">// Verifica se o usuário pode deletar o post</span>
        <span class="hljs-keyword">if</span> (Gate::authorize(<span class="hljs-string">'delete-post'</span>, $post)) {

            <span class="hljs-comment">// O usuário pode deletar o post</span>
            $post-&gt;delete();
            <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">'/posts'</span>);

        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// O usuário não tem permissão para deletar o post</span>
            abort(<span class="hljs-number">403</span>, <span class="hljs-string">'Você não tem permissão para excluir este post.'</span>);
        }
    }
}
</code></pre>
<p>Resultado. lança automaticamente uma Illuminate\Auth\Access\AuthorizationException:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721968275234/b31ccd35-c57d-4776-8ba7-37b2374b49bd.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-interceptando-verificacoes-de-gate">Interceptando verificações de gate</h3>
<p>Às vezes, você pode querer conceder todas as habilidades a um usuário específico. Você pode usar o método <code>before</code> para definir um fechamento que será executado antes de todas as outras verificações de autorização:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

Gate::before(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">User $user, <span class="hljs-keyword">string</span> $ability</span>) </span>{
    <span class="hljs-keyword">if</span> ($user-&gt;isAdministrator()) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
});
</code></pre>
<p>Se o fechamento anterior retornar um resultado não nulo, esse resultado será considerado o resultado da verificação de autorização.</p>
<p>Vamos criar um exemplo prático para entendermos o uso do Gate::before.</p>
<pre><code class="lang-php">Route::middleware(<span class="hljs-string">'auth'</span>)-&gt;group(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    Route::get(<span class="hljs-string">'/posts'</span>, [PostController::class, <span class="hljs-string">'index'</span>])-&gt;name(<span class="hljs-string">'posts.index'</span>);
    Route::get(<span class="hljs-string">'/post/{post}/edit'</span>, [PostController::class, <span class="hljs-string">'edit'</span>])-&gt;name(<span class="hljs-string">'post.edit'</span>);
    Route::patch(<span class="hljs-string">'/post/{post}'</span>, [PostController::class, <span class="hljs-string">'update'</span>])-&gt;name(<span class="hljs-string">'post.update'</span>);
    Route::delete(<span class="hljs-string">'/posts/{post}'</span>, [PostController::class, <span class="hljs-string">'destroy'</span>])-&gt;name(<span class="hljs-string">'post.delete'</span>);

    <span class="hljs-comment">// Crie as rotas abaixo:</span>
    Route::get(<span class="hljs-string">'/users'</span>, [UserController::class, <span class="hljs-string">'index'</span>])-&gt;name(<span class="hljs-string">'users.index'</span>);
    Route::post(<span class="hljs-string">'/users/{user}/toggle-admin'</span>, [UserController::class, <span class="hljs-string">'toggleAdmin'</span>])-&gt;name(<span class="hljs-string">'users.toggleAdmin'</span>);
});
</code></pre>
<p>Crie um controller para o user:</p>
<pre><code class="lang-php">sail artisan make:controller UserController
</code></pre>
<p>Código completo do UserController:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span>(<span class="hljs-params"></span>)
    </span>{
        $users = User::all();
        <span class="hljs-keyword">return</span> view(<span class="hljs-string">'users.index'</span>, compact(<span class="hljs-string">'users'</span>));
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toggleAdmin</span>(<span class="hljs-params">User $user</span>)
    </span>{
        $user-&gt;is_admin = !$user-&gt;is_admin;
        $user-&gt;save();

        <span class="hljs-keyword">return</span> redirect()-&gt;route(<span class="hljs-string">'users.index'</span>)-&gt;with(<span class="hljs-string">'success'</span>, <span class="hljs-string">'Status de administrador alterado com sucesso.'</span>);
    }
}
</code></pre>
<p>Vamos criar uma view para listar os usuários:</p>
<pre><code class="lang-php"><span class="hljs-comment">// resources/views/users/index.blade.php</span>
@<span class="hljs-keyword">extends</span>(<span class="hljs-string">'layouts.app'</span>)
@section(<span class="hljs-string">'content'</span>)
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">container</span>"&gt;
    &lt;<span class="hljs-title">h1</span>&gt;<span class="hljs-title">Lista</span> <span class="hljs-title">de</span> <span class="hljs-title">Usu</span>á<span class="hljs-title">rios</span>&lt;/<span class="hljs-title">h1</span>&gt;

    @<span class="hljs-title">if</span> (<span class="hljs-title">session</span>('<span class="hljs-title">success</span>'))
        &lt;<span class="hljs-title">div</span> <span class="hljs-title">style</span>="<span class="hljs-title">color</span>: <span class="hljs-title">green</span>;"&gt;
            </span>{{ session(<span class="hljs-string">'success'</span>) }}
        &lt;/div&gt;
    @<span class="hljs-keyword">endif</span>

    &lt;table border=<span class="hljs-string">"1"</span>&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;th&gt;ID&lt;/th&gt;
                &lt;th&gt;Nome&lt;/th&gt;
                &lt;th&gt;Email&lt;/th&gt;
                &lt;th&gt;Administrador&lt;/th&gt;
                &lt;th&gt;Ações&lt;/th&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            @<span class="hljs-keyword">foreach</span> ($users <span class="hljs-keyword">as</span> $user)
                &lt;tr&gt;
                    &lt;td&gt;{{ $user-&gt;id }}&lt;/td&gt;
                    &lt;td&gt;{{ $user-&gt;name }}&lt;/td&gt;
                    &lt;td&gt;{{ $user-&gt;email }}&lt;/td&gt;
                    &lt;td&gt;{{ $user-&gt;is_admin ? <span class="hljs-string">'Sim'</span> : <span class="hljs-string">'Não'</span> }}&lt;/td&gt;
                    &lt;td&gt;
                        &lt;form action=<span class="hljs-string">"{{ route('users.toggleAdmin', <span class="hljs-subst">$user</span>) }}"</span> method=<span class="hljs-string">"POST"</span>&gt;
                            @csrf
                            &lt;button type=<span class="hljs-string">"submit"</span>&gt;
                                {{ $user-&gt;is_admin ? <span class="hljs-string">'Remover Admin'</span> : <span class="hljs-string">'Tornar Admin'</span> }}
                            &lt;/button&gt;
                        &lt;/form&gt;
                    &lt;/td&gt;
                &lt;/tr&gt;
            @<span class="hljs-keyword">endforeach</span>
        &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;a href=<span class="hljs-string">"{{ url('/posts')  }}"</span>&gt;Ver Postagens&lt;/a&gt;
&lt;/div&gt;
@endsection
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148681996/4ac0377f-3221-499c-94bd-f0b9b4d484bd.png" alt class="image--center mx-auto" /></p>
<p>Agora na model User, adicione o seguinte código:</p>
<pre><code class="lang-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAdministrator</span>(<span class="hljs-params"></span>)
</span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;is_admin; <span class="hljs-comment">// Assume que 'is_admin' é uma coluna booleana na tabela 'users'</span>
}
</code></pre>
<p>Vamos criar uma migration para adicionar a coluna is_admin na tabela users:</p>
<pre><code class="lang-php">sail artisan make:migration add_is_admin_to_users_table --table=users
</code></pre>
<pre><code class="lang-php">Schema::table(<span class="hljs-string">'users'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
  <span class="hljs-comment">// Adiciona a coluna is_admin após a coluna email</span>
  $table-&gt;boolean(<span class="hljs-string">'is_admin'</span>)-&gt;default(<span class="hljs-literal">false</span>)-&gt;after(<span class="hljs-string">'email'</span>);
});

Schema::table(<span class="hljs-string">'users'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
  $table-&gt;dropColumn(<span class="hljs-string">'is_admin'</span>);
});
</code></pre>
<p>Execute o comando abaixo para atualizar a tabela users:</p>
<pre><code class="lang-php">sail artisan migrate
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148219835/ef7ed40c-da84-4299-af44-2a3c70639c83.png" alt class="image--center mx-auto" /></p>
<p>Veja que foi adicionado a coluna is_admin com o valor 0.</p>
<p>Altere para 1 o primeiro usuário:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148298544/23b7b00f-c55d-4437-8f8b-8bcf84ab7954.png" alt class="image--center mx-auto" /></p>
<p>Agora no front, observe que o usuário autenticado é o areadev e ele pode editar os posts do usuário bruno.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148416369/3b369744-7f06-47de-a68d-b207c0bd32f2.png" alt class="image--center mx-auto" /></p>
<p>Vamos definir um gate para visualizar a opção "Lista de usuários" quando o user autenticado for admin.</p>
<pre><code class="lang-php">Gate::define(<span class="hljs-string">'view-users'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">User $user</span>) </span>{
   <span class="hljs-keyword">return</span> $user-&gt;is_admin; 
});
</code></pre>
<p>Observe que para o usuário que não é admin, não aparece a opção "Lista de usuários" no canto inferior esquerdo da tela.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722148878104/5eac60e5-27e2-428b-8015-d19497e0f02f.png" alt class="image--center mx-auto" /></p>
<p>O método <code>Gate::after</code> permite que você execute uma lógica depois de todas as outras verificações de autorização. Isso é útil para fazer log ou auditoria das decisões de autorização, ou para aplicar regras adicionais depois das verificações normais:</p>
<pre><code class="lang-php"><span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">User</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Gate</span>;

Gate::after(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">User $user, $ability, $result, $arguments</span>) </span>{
  Log::info(<span class="hljs-string">'Autorização: '</span>, [
    <span class="hljs-string">'user_id'</span> =&gt; $user-&gt;id,
    <span class="hljs-string">'ability'</span> =&gt; $ability,
    <span class="hljs-string">'result'</span> =&gt; $result,
    <span class="hljs-string">'arguments'</span> =&gt; $arguments,
  ]);
});
</code></pre>
<p>Veja o arquivo <code>laravel.log</code> dentro da pasta <code>storage/logs</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722147352024/4a2dbcd8-47c2-4c5d-948c-b8a1b59396a2.png" alt class="image--center mx-auto" /></p>
<p>Semelhante ao método before, se o fechamento posterior retornar um resultado não nulo, esse resultado será considerado o resultado da verificação de autorização.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768486438740/adfcb785-ad7d-4aee-bc14-634ba6968718.jpeg" alt class="image--center mx-auto" /></a></p>
]]></content:encoded></item><item><title><![CDATA[Migrações e Seeders]]></title><description><![CDATA[https://www.youtube.com/watch?v=CUeo492WY4Y&t=293s
 

Introdução
Gerenciar o esquema do banco de dados de maneira controlada e repetível é uma necessidade crucial em qualquer aplicação. No Laravel, isso é facilitado por migrações e seeders.
As migraç...]]></description><link>https://areadev.com.br/migracoes-e-seeders</link><guid isPermaLink="true">https://areadev.com.br/migracoes-e-seeders</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Fri, 07 Jun 2024 17:07:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717779866709/e2ea311b-8e4a-49ea-8aa9-1e3f4ac32aab.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=CUeo492WY4Y&amp;t=293s">https://www.youtube.com/watch?v=CUeo492WY4Y&amp;t=293s</a></div>
<p> </p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768487067112/b2f182bc-f34f-4f44-b8ee-99be4c470cd7.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-introducao">Introdução</h4>
<p>Gerenciar o esquema do banco de dados de maneira controlada e repetível é uma necessidade crucial em qualquer aplicação. No Laravel, isso é facilitado por migrações e seeders.</p>
<p>As migrações permitem criar e modificar tabelas no banco de dados, enquanto os seeders são usados para popular tabelas com dados iniciais ou de teste.</p>
<h3 id="heading-migracoes">Migrações</h3>
<h5 id="heading-o-que-sao-migracoes">O Que São Migrações?</h5>
<p>Migrações são como controle de versão para o banco de dados. Elas permitem que você modifique a estrutura do banco de dados de maneira incremental e segura.</p>
<h5 id="heading-criando-uma-migracao">Criando uma Migração</h5>
<p>Você pode criar uma migração usando o Artisan CLI:</p>
<pre><code class="lang-bash">php artisan make:migration create_fruits_table
</code></pre>
<p>Isso criará um arquivo de migração em <code>database/migrations</code>. Um arquivo de migração típico tem dois métodos: <code>up</code> e <code>down</code>. O método <code>up</code> é usado para aplicar as alterações no banco de dados, enquanto o método <code>down</code> desfaz essas alterações.</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Migrations</span>\<span class="hljs-title">Migration</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Schema</span>\<span class="hljs-title">Blueprint</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Schema</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CreateFruitsTable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Migration</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span>(<span class="hljs-params"></span>)
    </span>{
        Schema::create(<span class="hljs-string">'fruits'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
            $table-&gt;id();
            $table-&gt;string(<span class="hljs-string">'name'</span>);
            $table-&gt;string(<span class="hljs-string">'color'</span>);    
            $table-&gt;timestamps();
        });
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">down</span>(<span class="hljs-params"></span>)
    </span>{
        Schema::dropIfExists(<span class="hljs-string">'fruits'</span>);
    }
}</span>
</code></pre>
<h5 id="heading-executando-migracoes">Executando Migrações</h5>
<p>Para executar todas as migrações pendentes, use o comando:</p>
<pre><code class="lang-bash">sail artisan migrate
</code></pre>
<p>Para reverter a última migração, use:</p>
<pre><code class="lang-bash">sail artisan migrate:rollback
</code></pre>
<h5 id="heading-modificando-tabelas-existentes">Modificando Tabelas Existentes</h5>
<p>Você pode criar uma migração para modificar uma tabela existente:</p>
<pre><code class="lang-bash">sail artisan make:migration add_price_to_fruits_table --table=fruits
</code></pre>
<p>No método <code>up</code>, você define as alterações:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span>(<span class="hljs-params"></span>)
    </span>{
        Schema::table(<span class="hljs-string">'fruits'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
            $table-&gt;integer(<span class="hljs-string">'price'</span>)-&gt;nullable();
        });
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">down</span>(<span class="hljs-params"></span>)
    </span>{
        Schema::table(<span class="hljs-string">'fruits'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Blueprint $table</span>) </span>{
            $table-&gt;dropColumn(<span class="hljs-string">'price'</span>);
        });
    }</span>
</code></pre>
<h3 id="heading-seeders">Seeders</h3>
<h5 id="heading-o-que-sao-seeders">O Que São Seeders?</h5>
<p>Seeders são classes usadas para popular o banco de dados com dados iniciais ou de teste. Eles são úteis para preencher tabelas com dados que você pode usar durante o desenvolvimento ou para testar sua aplicação.</p>
<h5 id="heading-criando-um-seeder">Criando um Seeder</h5>
<p>Você pode criar um seeder usando o Artisan CLI:</p>
<pre><code class="lang-bash">sail artisan make:seeder FruitsTableSeeder
</code></pre>
<p>Isso criará um arquivo de seeder em <code>database/seeders</code>. Você pode definir os dados a serem inseridos no método <code>run</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Seeder</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Fruit</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FruitsTableSeeder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Seeder</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params"></span>)
    </span>{
        Fruit::create([
            <span class="hljs-string">'name'</span> =&gt; <span class="hljs-string">'Abacaxi'</span>,
            <span class="hljs-string">'color'</span> =&gt; <span class="hljs-string">'Amarelo'</span>,
        ]);

        Fruit::create([
            <span class="hljs-string">'name'</span> =&gt; <span class="hljs-string">'Banana'</span>,
            <span class="hljs-string">'color'</span> =&gt; <span class="hljs-string">'Amarela'</span>,
        ]);
    }
}</span>
</code></pre>
<h5 id="heading-executando-seeders">Executando Seeders</h5>
<p>Para executar todos os seeders, use o comando:</p>
<pre><code class="lang-bash">sail artisan db:seed
</code></pre>
<p>Lembre-se de adicionar o seeder criado dentro do DatabaseSeeder.php</p>
<pre><code class="lang-php-template"><span class="xml">$this-&gt;call(FruitsTableSeeder::class);</span>
</code></pre>
<p>Para executar um seeder específico, use:</p>
<pre><code class="lang-bash">sail artisan db:seed --class=FruitsTableSeeder
</code></pre>
<h3 id="heading-models">Models</h3>
<p>Uma <strong>model</strong> no Laravel (e em muitos outros frameworks MVC - Model-View-Controller) é uma classe que representa uma entidade da aplicação, geralmente ligada a uma tabela específica no banco de dados. A model serve como a camada intermediária entre a aplicação e o banco de dados, facilitando o gerenciamento de dados.</p>
<pre><code class="lang-php-template"><span class="xml">sail artisan make:model Fruit</span>
</code></pre>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Eloquent</span>\<span class="hljs-title">Factories</span>\<span class="hljs-title">HasFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Eloquent</span>\<span class="hljs-title">Model</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Fruit</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
</span>{
    <span class="hljs-keyword">use</span> <span class="hljs-title">HasFactory</span>;

    <span class="hljs-keyword">protected</span> $fillable = [
        <span class="hljs-string">'name'</span>,
        <span class="hljs-string">'color'</span>,
        <span class="hljs-string">'price'</span>,
    ];
}</span>
</code></pre>
<h3 id="heading-factories-e-seeders">Factories e Seeders</h3>
<p>Factories são frequentemente usadas em conjunto com seeders para gerar dados de teste realistas. Primeiro, você cria uma factory:</p>
<pre><code class="lang-bash">sail artisan make:factory FruitFactory --model=Fruit
</code></pre>
<p>No arquivo da factory, você define como os dados fictícios devem ser gerados:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Database</span>\<span class="hljs-title">Factories</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Fruit</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Eloquent</span>\<span class="hljs-title">Factories</span>\<span class="hljs-title">Factory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Str</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FruitFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Factory</span>
</span>{
    <span class="hljs-keyword">protected</span> $model = Fruit::class;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">definition</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-string">'name'</span> =&gt; <span class="hljs-keyword">$this</span>-&gt;faker-&gt;word,
            <span class="hljs-string">'color'</span> =&gt; <span class="hljs-keyword">$this</span>-&gt;faker-&gt;safeColorName,
            <span class="hljs-string">'price'</span> =&gt; <span class="hljs-keyword">$this</span>-&gt;faker-&gt;randomFloat(<span class="hljs-number">2</span>, <span class="hljs-number">1000</span>, <span class="hljs-number">5000</span>),
        ];
    }
}</span>
</code></pre>
<p>No seeder, você pode usar a factory para criar múltiplos registros:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Seeder</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Fruit</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FruitsTableSeeder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Seeder</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params"></span>)
    </span>{
        Fruit::factory()-&gt;count(<span class="hljs-number">10</span>)-&gt;create();
    }
}</span>
</code></pre>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768487082750/061b24fe-310e-4615-af50-7e62e1195425.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Migrações e seeders são ferramentas poderosas no Laravel para gerenciar o esquema do banco de dados e popular tabelas de forma controlada e repetível. Elas permitem que você mantenha o banco de dados sincronizado e cheio de dados úteis durante o desenvolvimento e testes. Nos próximos tópicos, exploraremos outras funcionalidades avançadas do Laravel para continuar aprimorando suas habilidades no desenvolvimento de aplicações robustas e eficientes.</p>
]]></content:encoded></item><item><title><![CDATA[Eloquent ORM e Modelos]]></title><description><![CDATA[Introdução ao Eloquent ORM
Eloquent ORM (Object-Relational Mapping) é o mapeador de objetos-relacionais do Laravel, que facilita a interação com o banco de dados. Com o Eloquent, você pode trabalhar com seus dados de maneira intuitiva e orientada a o...]]></description><link>https://areadev.com.br/eloquent-orm-e-modelos</link><guid isPermaLink="true">https://areadev.com.br/eloquent-orm-e-modelos</guid><category><![CDATA[Laravel]]></category><category><![CDATA[PHP]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Bruno Development]]></dc:creator><pubDate>Thu, 06 Jun 2024 03:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717776722208/c7cf5d37-b670-4eda-9449-218c7ca54db9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-introducao-ao-eloquent-orm">Introdução ao Eloquent ORM</h4>
<p>Eloquent ORM (Object-Relational Mapping) é o mapeador de objetos-relacionais do Laravel, que facilita a interação com o banco de dados. Com o Eloquent, você pode trabalhar com seus dados de maneira intuitiva e orientada a objetos, sem precisar escrever consultas SQL complexas.</p>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768488991945/a6f0a6dc-0a22-48de-96d3-4cf6d395bbdd.jpeg" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-definicao-de-modelos">Definição de Modelos</h4>
<p>Os modelos no Eloquent representam as tabelas do banco de dados. Cada modelo é responsável por interagir com uma tabela específica e suas respectivas colunas.</p>
<h5 id="heading-criando-um-modelo">Criando um Modelo</h5>
<p>Você pode criar um modelo usando o Artisan CLI:</p>
<pre><code class="lang-bash">php artisan make:model NomeDoModelo
</code></pre>
<p>Isso criará um arquivo de modelo em <code>app/Models/NomeDoModelo.php</code>. Um modelo básico pode parecer assim:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Eloquent</span>\<span class="hljs-title">Factories</span>\<span class="hljs-title">HasFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Database</span>\<span class="hljs-title">Eloquent</span>\<span class="hljs-title">Model</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NomeDoModelo</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
</span>{
    <span class="hljs-keyword">use</span> <span class="hljs-title">HasFactory</span>;
}</span>
</code></pre>
<p>Por padrão, o modelo assume que a tabela associada tem o nome pluralizado em inglês do nome do modelo (por exemplo, um modelo <code>User</code> se relaciona à tabela <code>users</code>). Você pode especificar explicitamente a tabela usando a propriedade <code>$table</code>:</p>
<pre><code class="lang-php-template"><span class="php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NomeDoModelo</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
</span>{
    <span class="hljs-keyword">protected</span> $table = <span class="hljs-string">'nome_da_tabela'</span>;
}</span>
</code></pre>
<h5 id="heading-trabalhando-com-modelos">Trabalhando com Modelos</h5>
<p>Com um modelo definido, você pode realizar várias operações de banco de dados. Aqui estão alguns exemplos:</p>
<ul>
<li><p><strong>Recuperando todos os registros:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span> $users = User::all();</span>
</code></pre>
</li>
<li><p><strong>Encontrando um registro por ID:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span> $user = User::find(<span class="hljs-number">1</span>);</span>
</code></pre>
</li>
<li><p><strong>Criando um novo registro:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span> 
      $user = <span class="hljs-keyword">new</span> User;
      $user-&gt;name = <span class="hljs-string">'John Doe'</span>;
      $user-&gt;email = <span class="hljs-string">'john@example.com'</span>;
      $user-&gt;save();</span>
</code></pre>
</li>
<li><p><strong>Atualizando um registro existente:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span> 
      $user = User::find(<span class="hljs-number">1</span>);
      $user-&gt;name = <span class="hljs-string">'Jane Doe'</span>;
      $user-&gt;save();</span>
</code></pre>
</li>
<li><p><strong>Excluindo um registro:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      $user = User::find(<span class="hljs-number">1</span>);
      $user-&gt;delete();</span>
</code></pre>
</li>
</ul>
<h4 id="heading-relacionamentos">Relacionamentos</h4>
<p>O Eloquent facilita a definição e o trabalho com relacionamentos entre modelos. Existem vários tipos de relacionamentos, incluindo one-to-one, one-to-many e many-to-many.</p>
<h5 id="heading-one-to-one">One-to-One</h5>
<p>Um relacionamento one-to-one ocorre quando uma linha em uma tabela está associada a exatamente uma linha em outra tabela.</p>
<ul>
<li><p><strong>Definindo um relacionamento one-to-one:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">phone</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;hasOne(Phone::class);
          }
      }

      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Phone</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">user</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;belongsTo(User::class);
          }
      }</span>
</code></pre>
</li>
<li><p><strong>Usando um relacionamento one-to-one:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      $user = User::find(<span class="hljs-number">1</span>);
      $phone = $user-&gt;phone;</span>
</code></pre>
</li>
</ul>
<h5 id="heading-one-to-many">One-to-Many</h5>
<p>Um relacionamento one-to-many ocorre quando uma linha em uma tabela pode estar associada a várias linhas em outra tabela.</p>
<ul>
<li><p><strong>Definindo um relacionamento one-to-many:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Post</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">comments</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;hasMany(Comment::class);
          }
      }

      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Comment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">post</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;belongsTo(Post::class);
          }
      }</span>
</code></pre>
</li>
<li><p><strong>Usando um relacionamento one-to-many:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      $post = Post::find(<span class="hljs-number">1</span>);
      $comments = $post-&gt;comments;</span>
</code></pre>
</li>
</ul>
<h5 id="heading-many-to-many">Many-to-Many</h5>
<p>Um relacionamento many-to-many ocorre quando várias linhas em uma tabela estão associadas a várias linhas em outra tabela. Esse tipo de relacionamento usa uma tabela intermediária.</p>
<ul>
<li><p><strong>Definindo um relacionamento many-to-many:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">roles</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;belongsToMany(Role::class);
          }
      }

      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Role</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
      </span>{
          <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">users</span>(<span class="hljs-params"></span>)
          </span>{
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;belongsToMany(User::class);
          }
      }</span>
</code></pre>
</li>
<li><p><strong>Usando um relacionamento many-to-many:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      $user = User::find(<span class="hljs-number">1</span>);
      $roles = $user-&gt;roles;</span>
</code></pre>
</li>
<li><p><strong>Sincronizando relacionamentos many-to-many:</strong></p>
<pre><code class="lang-php-template"><span class="xml">  </span><span class="php"><span class="hljs-meta">&lt;?php</span>
      $user = User::find(<span class="hljs-number">1</span>);
      $user-&gt;roles()-&gt;sync([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);</span>
</code></pre>
</li>
</ul>
<p><a target="_blank" href="https://www.udemy.com/course/logica-de-programacao-com-pascalzim/?referralCode=E547897C16AD4FF23AED"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768489010859/83ad7b38-c99b-4abf-98a7-25b922ddea9a.jpeg" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>O Eloquent ORM é uma ferramenta poderosa que facilita a interação com o banco de dados de forma intuitiva e eficiente. Com a definição de modelos e relacionamentos, você pode manipular os dados da sua aplicação de maneira estruturada e orientada a objetos. Nos próximos tópicos, exploraremos mais funcionalidades avançadas do Laravel, incluindo migrations, seeders e factories, para facilitar o desenvolvimento e a gestão do banco de dados.</p>
]]></content:encoded></item></channel></rss>