<?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" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[JCMaciel Blog]]></title><description><![CDATA[Ruby on Rails, SaaS and AI]]></description><link>https://jcmaciel.com/</link><image><url>https://jcmaciel.com/favicon.png</url><title>JCMaciel Blog</title><link>https://jcmaciel.com/</link></image><generator>Ghost 5.88</generator><lastBuildDate>Fri, 17 Apr 2026 16:48:47 GMT</lastBuildDate><atom:link href="https://jcmaciel.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Ruby on Rails 8: Principais Novidades e Dicas de Atualização]]></title><description><![CDATA[<p>Ruby on Rails 8 chegou trazendo uma s&#xE9;rie de melhorias e novidades que prometem tornar o desenvolvimento web ainda mais eficiente e produtivo. Neste artigo, exploraremos as principais mudan&#xE7;as introduzidas nesta nova vers&#xE3;o e forneceremos dicas valiosas para ajudar voc&#xEA; a atualizar seus</p>]]></description><link>https://jcmaciel.com/ruby-on-rails-8-principais-novidades-e-dicas-de-atualizacao/</link><guid isPermaLink="false">672e0f2818f08500018391d2</guid><category><![CDATA[Engenharia de Software]]></category><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[Rails]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Software]]></category><category><![CDATA[Programação]]></category><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Fri, 08 Nov 2024 13:17:48 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1487058792275-0ad4aaf24ca7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEyfHxwcm9ncmFtbWluZ3xlbnwwfHx8fDE3MzEwNzE4NDh8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1487058792275-0ad4aaf24ca7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEyfHxwcm9ncmFtbWluZ3xlbnwwfHx8fDE3MzEwNzE4NDh8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Ruby on Rails 8: Principais Novidades e Dicas de Atualiza&#xE7;&#xE3;o"><p>Ruby on Rails 8 chegou trazendo uma s&#xE9;rie de melhorias e novidades que prometem tornar o desenvolvimento web ainda mais eficiente e produtivo. Neste artigo, exploraremos as principais mudan&#xE7;as introduzidas nesta nova vers&#xE3;o e forneceremos dicas valiosas para ajudar voc&#xEA; a atualizar seus sistemas antigos para o Rails 8.</p><h2 id="sum%C3%A1rio">Sum&#xE1;rio</h2><ol><li><a>Introdu&#xE7;&#xE3;o</a></li><li><a>Principais Novidades do Rails 8</a><ul><li><a>Active Support</a></li><li><a>Active Model</a></li><li><a>Active Record</a></li><li><a>Action View</a></li><li><a>Action Pack</a></li><li><a>Active Job</a></li><li><a>Railties</a></li></ul></li><li><a>Dicas para Atualizar Sistemas Antigos para o Rails 8</a></li><li><a>Conclus&#xE3;o</a></li></ol><h2 id="introdu%C3%A7%C3%A3o">Introdu&#xE7;&#xE3;o</h2><p>Ruby on Rails &#xE9; um dos frameworks web mais populares, conhecido por sua filosofia de &quot;conven&#xE7;&#xE3;o sobre configura&#xE7;&#xE3;o&quot; e por acelerar o processo de desenvolvimento. A vers&#xE3;o 8 do Rails traz aprimoramentos significativos em diversas &#xE1;reas, desde melhorias de desempenho at&#xE9; a introdu&#xE7;&#xE3;o de novos recursos que facilitam a vida dos desenvolvedores.</p><p>Neste artigo, vamos nos aprofundar nas principais novidades do Rails 8 e oferecer orienta&#xE7;&#xF5;es pr&#xE1;ticas para atualizar aplica&#xE7;&#xF5;es existentes, garantindo uma transi&#xE7;&#xE3;o suave para esta nova vers&#xE3;o.</p><h2 id="principais-novidades-do-rails-8">Principais Novidades do Rails 8</h2><h3 id="active-support">Active Support</h3><p><strong>1. Remo&#xE7;&#xE3;o de Funcionalidades Obsoletas</strong></p><ul><li><strong>Arrays em ActiveSupport::Deprecation#warn</strong>: O suporte a passagem de um array de strings para <code>ActiveSupport::Deprecation#warn</code> foi removido, incentivando o uso de mensagens de deprecia&#xE7;&#xE3;o mais claras.</li><li><strong>Formato de Nomea&#xE7;&#xE3;o de Atributos Internos</strong>: O suporte a <code>attr_internal_naming_format</code> com prefixo <code>@</code> foi eliminado, padronizando a forma como os atributos internos s&#xE3;o nomeados.</li><li><strong>ActiveSupport::ProxyObject</strong>: Esta classe foi removida, simplificando a hierarquia de objetos proxy.</li></ul><p><strong>2. Otimiza&#xE7;&#xF5;es de Desempenho</strong></p><ul><li><strong>Watcher de I18n</strong>: O watcher de internacionaliza&#xE7;&#xE3;o n&#xE3;o &#xE9; mais executado durante o boot da aplica&#xE7;&#xE3;o, o que melhora o tempo de inicializa&#xE7;&#xE3;o, especialmente em aplica&#xE7;&#xF5;es com muitas tradu&#xE7;&#xF5;es.</li><li><strong>HashWithIndifferentAccess</strong>: O m&#xE9;todo <code>stringify_keys</code> agora converte todas as chaves em strings, n&#xE3;o apenas s&#xED;mbolos, corrigindo comportamentos inesperados.</li></ul><p><strong>3. Melhorias em Instrumenta&#xE7;&#xE3;o e Logging</strong></p><ul><li><strong>Instrumenta&#xE7;&#xE3;o de Cache</strong>: Os m&#xE9;todos <code>delete</code> e <code>delete_multi</code> de <code>ActiveSupport::Cache::Store</code> agora incluem op&#xE7;&#xF5;es ao serem instrumentados, fornecendo mais contexto durante o monitoramento.</li><li><strong>Exibi&#xE7;&#xE3;o de Nomes de Testes</strong>: Ao executar testes com <code>rails test -v</code> em modo paralelo, os nomes dos testes s&#xE3;o exibidos, facilitando a identifica&#xE7;&#xE3;o.</li></ul><h3 id="active-model">Active Model</h3><p><strong>1. Novas Op&#xE7;&#xF5;es de Valida&#xE7;&#xE3;o</strong></p><ul><li><strong>Token Padr&#xE3;o para Reset de Senha</strong>: A introdu&#xE7;&#xE3;o de um gerador de token padr&#xE3;o facilita a implementa&#xE7;&#xE3;o de funcionalidades de reset de senha usando <code>has_secure_password</code>.</li></ul><p><strong>:except_on</strong>: Agora &#xE9; poss&#xED;vel usar <code>:except_on</code> em valida&#xE7;&#xF5;es para especificar contextos nos quais a valida&#xE7;&#xE3;o deve ser ignorada. Por exemplo:</p><pre><code class="language-ruby">class User &lt; ApplicationRecord
  validates :birthday, presence: { except_on: :admin }
end
</code></pre><h3 id="active-record">Active Record</h3><p><strong>1. Melhorias em Migra&#xE7;&#xF5;es e Esquemas</strong></p><ul><li><strong>Carregamento de Seeds</strong>: O task <code>db:prepare</code> n&#xE3;o carrega mais seeds ao criar um banco de dados n&#xE3;o prim&#xE1;rio, evitando perda potencial de dados em ambientes existentes.</li></ul><p><strong>Suporte a V&#xE1;rias Tabelas em <code>drop_table</code></strong>: Agora &#xE9; poss&#xED;vel passar um array de nomes para <code>drop_table</code>, permitindo a remo&#xE7;&#xE3;o de m&#xFA;ltiplas tabelas em uma &#xFA;nica chamada.</p><pre><code class="language-ruby">ActiveRecord::Base.connection.drop_table(:users, :posts)
</code></pre><p><strong>2. Novas Funcionalidades em Consultas</strong></p><ul><li><strong>Otimiza&#xE7;&#xF5;es em <code>in_order_of</code></strong>: Adicionada a op&#xE7;&#xE3;o de filtro para priorizar certos valores na ordena&#xE7;&#xE3;o sem filtrar os resultados.</li><li><strong>Suporte a Hashes em <code>pluck</code></strong>: <code>pluck</code> agora aceita argumentos de hash com valores de s&#xED;mbolos e strings, aumentando a flexibilidade nas consultas.</li></ul><p><strong>3. Melhorias em Tipos e Colunas</strong></p><ul><li><strong>Distin&#xE7;&#xE3;o entre <code>float4</code> e <code>float8</code> no PostgreSQL</strong>: Agora o Active Record distingue corretamente entre os tipos de ponto flutuante do PostgreSQL.</li><li><strong>Deprecia&#xE7;&#xE3;o de M&#xE9;todos</strong>: Os m&#xE9;todos <code>unsigned_float</code> e <code>unsigned_decimal</code> foram depreciados, seguindo as mudan&#xE7;as no MySQL 8.0.17.</li></ul><h3 id="action-view">Action View</h3><p><strong>1. Renomea&#xE7;&#xE3;o de M&#xE9;todos</strong></p><ul><li><strong><code>text_area</code> para <code>textarea</code></strong>: Os m&#xE9;todos <code>text_area</code> foram renomeados para <code>textarea</code> para alinhar com as conven&#xE7;&#xF5;es HTML. Os nomes antigos ainda est&#xE3;o dispon&#xED;veis como aliases.</li><li><strong><code>check_box</code> para <code>checkbox</code></strong>: Similarmente, os m&#xE9;todos <code>check_box</code> foram renomeados para <code>checkbox</code>.</li></ul><p><strong>2. Melhorias no DependencyTracker</strong></p><ul><li><strong>Renderiza&#xE7;&#xE3;o com Interpola&#xE7;&#xE3;o</strong>: O <code>DependencyTracker</code> agora avalia corretamente renders com interpola&#xE7;&#xE3;o, garantindo que todas as depend&#xEA;ncias sejam rastreadas.</li></ul><h3 id="action-pack">Action Pack</h3><p><strong>1. Atualiza&#xE7;&#xF5;es em Rotas</strong></p><ul><li><strong>Corre&#xE7;&#xE3;o em Rotas com <code>::</code></strong>: Problemas em rotas contendo <code>::</code> foram corrigidos, permitindo rotas mais complexas.</li><li><strong>Argumentos Inv&#xE1;lidos em Recursos</strong>: Agora, passar op&#xE7;&#xF5;es inv&#xE1;lidas como <code>:only</code> ou <code>:except</code> em <code>resource</code> e <code>resources</code> gera um <code>ArgumentError</code>, ajudando a identificar erros de configura&#xE7;&#xE3;o.</li></ul><p><strong>2. Novos M&#xE9;todos de Par&#xE2;metros</strong></p><p><code><strong>params#expect</strong></code>: Introduzido um m&#xE9;todo mais seguro e expl&#xED;cito para manipula&#xE7;&#xE3;o de par&#xE2;metros, substituindo <code>params.require</code> e <code>params.permit</code>.</p><pre><code class="language-ruby">params.expect(person: [:name, :age, pets: [[:name]]])
</code></pre><p><strong>3. Melhorias em Testes</strong></p><ul><li><strong>Atualiza&#xE7;&#xE3;o de Cookies em Requisi&#xE7;&#xF5;es N&#xE3;o-GET</strong>: Corre&#xE7;&#xE3;o em <code>ActionController::TestCase</code> para garantir que cookies sejam atualizados corretamente em requisi&#xE7;&#xF5;es de outros m&#xE9;todos HTTP.</li></ul><h3 id="active-job">Active Job</h3><p><strong>1. Atualiza&#xE7;&#xF5;es em Adaptadores</strong></p><ul><li><strong>Deprecia&#xE7;&#xE3;o do <code>sucker_punch</code></strong>: O adaptador <code>sucker_punch</code> foi depreciado. Recomenda-se o uso de <code>adapter: async</code> para funcionalidade semelhante.</li><li><strong>Uso de <code>RAILS_MAX_THREADS</code></strong>: O <code>ActiveJob::AsyncAdapter</code> agora utiliza <code>RAILS_MAX_THREADS</code>, com valor padr&#xE3;o de 5 se n&#xE3;o definido.</li></ul><h3 id="railties">Railties</h3><p><strong>1. Novos Geradores e Configura&#xE7;&#xF5;es</strong></p><p><strong>Script Generator</strong>: Adicionada uma pasta <code>script</code> e um gerador de scripts para facilitar a cria&#xE7;&#xE3;o de scripts &#xFA;nicos ou de prop&#xF3;sito geral.</p><pre><code class="language-bash">bin/rails generate script my_script
</code></pre><p><strong>Gerador de Autentica&#xE7;&#xE3;o</strong>: Um novo gerador para iniciar um sistema b&#xE1;sico de autentica&#xE7;&#xE3;o usando sess&#xF5;es e reset de senha.</p><pre><code class="language-bash">bin/rails generate authentication
</code></pre><p><strong>2. Altera&#xE7;&#xF5;es em Configura&#xE7;&#xF5;es Padr&#xE3;o</strong></p><ul><li><strong>Uso do Solid Cable e Solid Queue</strong>: O Rails 8 agora usa o Solid Cable como adaptador padr&#xE3;o do Action Cable e o Solid Queue como backend padr&#xE3;o do Active Job, ambos configurados para melhorar o desempenho sem depender de Redis.</li></ul><p><strong>3. Melhorias em Desempenho</strong></p><ul><li><strong>Deferimento de Rotas</strong>: O carregamento das rotas &#xE9; adiado para a primeira requisi&#xE7;&#xE3;o ou quando <code>url_helpers</code> s&#xE3;o chamados, melhorando o tempo de boot em aplica&#xE7;&#xF5;es maiores.</li></ul><h2 id="dicas-para-atualizar-sistemas-antigos-para-o-rails-8">Dicas para Atualizar Sistemas Antigos para o Rails 8</h2><p>Atualizar uma aplica&#xE7;&#xE3;o existente para uma nova vers&#xE3;o do Rails pode ser desafiador. Aqui est&#xE3;o algumas dicas para facilitar esse processo:</p><ol><li><strong>Leia as Notas de Vers&#xE3;o</strong>: Antes de iniciar, leia cuidadosamente as notas de vers&#xE3;o do Rails 8 para entender todas as mudan&#xE7;as e deprecia&#xE7;&#xF5;es.</li><li><strong>Atualize Gradualmente</strong>: Se sua aplica&#xE7;&#xE3;o est&#xE1; em uma vers&#xE3;o muito antiga, considere atualizar para vers&#xF5;es intermedi&#xE1;rias primeiro (por exemplo, do Rails 5 para o 6, depois para o 7, e finalmente para o 8).</li><li><strong>Teste Extensivamente</strong>: Utilize uma su&#xED;te de testes abrangente para garantir que as funcionalidades existentes continuem operando conforme esperado ap&#xF3;s a atualiza&#xE7;&#xE3;o.</li><li><strong>Revise Deprecia&#xE7;&#xF5;es</strong>: Procure por avisos de deprecia&#xE7;&#xE3;o ao executar sua aplica&#xE7;&#xE3;o e atualize o c&#xF3;digo conforme necess&#xE1;rio.</li><li><strong>Atualize Depend&#xEA;ncias</strong>: Certifique-se de que todas as gemas e bibliotecas externas sejam compat&#xED;veis com o Rails 8, atualizando-as para vers&#xF5;es mais recentes quando necess&#xE1;rio.</li><li><strong>Verifique Configura&#xE7;&#xF5;es Personalizadas</strong>: Se voc&#xEA; personalizou configura&#xE7;&#xF5;es ou utilizou APIs internas, revise essas &#xE1;reas cuidadosamente, pois elas podem ter mudado.</li><li><strong>Considere as Novas Funcionalidades</strong>: Aproveite a atualiza&#xE7;&#xE3;o para refatorar partes da aplica&#xE7;&#xE3;o que podem se beneficiar das novas funcionalidades introduzidas no Rails 8.</li><li><strong>Planeje Tempo Adequado</strong>: Reserve tempo suficiente para a atualiza&#xE7;&#xE3;o, testes e poss&#xED;veis corre&#xE7;&#xF5;es de bugs que possam surgir.</li><li><strong>Colabore com a Equipe</strong>: Envolva outros desenvolvedores do seu time no processo de atualiza&#xE7;&#xE3;o para compartilhar conhecimentos e agilizar a resolu&#xE7;&#xE3;o de problemas.</li><li><strong>Fa&#xE7;a Backup</strong>: Sempre fa&#xE7;a backup do banco de dados e do c&#xF3;digo antes de iniciar o processo de atualiza&#xE7;&#xE3;o.</li></ol><h2 id="conclus%C3%A3o">Conclus&#xE3;o</h2><p>O Ruby on Rails 8 traz avan&#xE7;os significativos que podem melhorar a efici&#xEA;ncia e a produtividade no desenvolvimento web. Com novas funcionalidades, otimiza&#xE7;&#xF5;es de desempenho e melhorias na seguran&#xE7;a, &#xE9; uma atualiza&#xE7;&#xE3;o que vale a pena considerar.</p><p>Ao planejar e executar cuidadosamente a atualiza&#xE7;&#xE3;o de sistemas antigos, voc&#xEA; pode aproveitar ao m&#xE1;ximo os benef&#xED;cios desta nova vers&#xE3;o, garantindo que sua aplica&#xE7;&#xE3;o permane&#xE7;a moderna, segura e eficiente.</p><p>Esperamos que este artigo tenha fornecido insights valiosos sobre as novidades do Rails 8 e orienta&#xE7;&#xF5;es &#xFA;teis para facilitar o processo de atualiza&#xE7;&#xE3;o. Mantenha-se sempre atualizado com as &#xFA;ltimas tend&#xEA;ncias e boas pr&#xE1;ticas para continuar desenvolvendo aplica&#xE7;&#xF5;es web de alta qualidade.</p>]]></content:encoded></item><item><title><![CDATA[Atualizando do Kamal 1 para o Kamal 2]]></title><description><![CDATA[<p>Aqui est&#xE3;o alguns passos e notas para a atualiza&#xE7;&#xE3;o de uma configura&#xE7;&#xE3;o de servidor &#xFA;nico do Kamal para o novo Kamal 2.</p><h3 id="1-atualizar-para-o-kamal-19x">1. Atualizar para o Kamal 1.9.x</h3><p>Primeiro, atualize para o Kamal 1.9 e confirme se ainda</p>]]></description><link>https://jcmaciel.com/atualizando-do-kamal-1-para-o-kamal-2/</link><guid isPermaLink="false">6717a3bc18f08500018391c5</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Tue, 22 Oct 2024 13:09:05 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1522776851755-3914469f0ca2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJ1Ynl8ZW58MHx8fHwxNzI5NjAyNTM1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1522776851755-3914469f0ca2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJ1Ynl8ZW58MHx8fHwxNzI5NjAyNTM1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Atualizando do Kamal 1 para o Kamal 2"><p>Aqui est&#xE3;o alguns passos e notas para a atualiza&#xE7;&#xE3;o de uma configura&#xE7;&#xE3;o de servidor &#xFA;nico do Kamal para o novo Kamal 2.</p><h3 id="1-atualizar-para-o-kamal-19x">1. Atualizar para o Kamal 1.9.x</h3><p>Primeiro, atualize para o Kamal 1.9 e confirme se ainda consegue realizar o deploy:</p><pre><code class="language-bash">$ gem install kamal --version 1.9.0
$ kamal config
$ kamal deploy</code></pre><h3 id="2-atualizar-para-o-kamal-2">2. Atualizar para o Kamal 2</h3><p>Atualize novamente a vers&#xE3;o do Kamal para um lan&#xE7;amento 2.x:</p><pre><code class="language-bash">$ gem install kamal --version 2.1.0
</code></pre><p>N&#xE3;o realize o deploy ainda.</p><h3 id="3-remover-refer%C3%AAncias-ao-traefik">3. Remover refer&#xEA;ncias ao Traefik</h3><p>Remova a se&#xE7;&#xE3;o Traefik de <code>config/deploy.yml</code>:</p><pre><code class="language-yaml">traefik:
  options:
    publish:
      - &quot;443:443&quot;
    volume:
      - &quot;/letsencrypt/acme.json:/letsencrypt/acme.json&quot;
    network: &quot;private&quot;
  ...
</code></pre><p>E remova qualquer outra refer&#xEA;ncia ao proxy, como r&#xF3;tulos <code>traefik.*</code> em qualquer lugar.</p><h3 id="4-remover-a-se%C3%A7%C3%A3o-de-verifica%C3%A7%C3%A3o-de-sa%C3%BAde-healthcheck">4. Remover a se&#xE7;&#xE3;o de verifica&#xE7;&#xE3;o de sa&#xFA;de (healthcheck)</h3><p>Remova as configura&#xE7;&#xF5;es antigas de healthcheck de <code>config/deploy.yml</code>:</p><pre><code class="language-yaml">healthcheck:
  # path: /up
  # port: 3000
  interval: 5s
</code></pre><h3 id="5-atualizar-a-configura%C3%A7%C3%A3o-do-builder">5. Atualizar a configura&#xE7;&#xE3;o do builder</h3><p>Remova a op&#xE7;&#xE3;o <code>multiarch</code> e especifique uma ou mais arquiteturas com <code>arch</code> (as op&#xE7;&#xF5;es s&#xE3;o <code>amd64</code> e <code>arm64</code>):</p><pre><code class="language-yaml">builder:
  arch: 
    - amd64
    - arm64
</code></pre><p>Voc&#xEA; provavelmente usar&#xE1; <code>amd64</code>. Pode manter as configura&#xE7;&#xF5;es de cache.</p><p>Consulte o guia oficial para builders remotos.</p><h3 id="6-adicionar-as-novas-configura%C3%A7%C3%B5es-de-proxy">6. Adicionar as novas configura&#xE7;&#xF5;es de proxy</h3><p>Adicione configura&#xE7;&#xF5;es semelhantes de Kamal Proxy de acordo com suas necessidades:</p><pre><code class="language-yaml">proxy:
  ssl: true
  host: tubeandchill.com
  app_port: 3000
  healthcheck:
    path: /up
    interval: 3
    timeout: 30
</code></pre><p>Se voc&#xEA; estava emitindo certificados TLS com o Traefik, agora pode substitu&#xED;-lo definindo <code>ssl</code> como <code>true</code> e especificando seu host. Caso contr&#xE1;rio, pode pular esta etapa.</p><p>O caminho de healthcheck permaneceu o mesmo em <code>/up</code>, mas voc&#xEA; pode precisar remov&#xEA;-lo das verifica&#xE7;&#xF5;es de SSL ou hostname:</p><pre><code class="language-ruby"># Ignora redirecionamento de http para https para o endpoint padr&#xE3;o de healthcheck.
config.ssl_options = { redirect: { exclude: -&gt;(request) { request.path == &quot;/up&quot; } } }

# Ignora prote&#xE7;&#xE3;o de reatribui&#xE7;&#xE3;o de DNS para o endpoint padr&#xE3;o de healthcheck.
config.host_authorization = { exclude: -&gt;(request) { request.path == &quot;/up&quot; } }
</code></pre><p>A porta da aplica&#xE7;&#xE3;o agora est&#xE1; definida para 80 (era 3000). Altere-a de volta para 3000 ou atualize seu Dockerfile para usar a porta 80.</p><h3 id="7-criar-novo-arquivo-de-secrets">7. Criar novo arquivo de secrets</h3><p>O Kamal mudou a forma como os secrets funcionam. Antes de explorar as novas op&#xE7;&#xF5;es de secrets, voc&#xEA; pode simplesmente mover os antigos:</p><pre><code class="language-bash">$ cp .env .kamal/secrets
</code></pre><p>Isso significa que <code>.kamal/secrets</code> tamb&#xE9;m n&#xE3;o pode ser inclu&#xED;do no controle de vers&#xE3;o, ent&#xE3;o adicione-o ao <code>.gitignore</code>.</p><p>Voc&#xEA; pode explorar os novos secrets em mais detalhes na documenta&#xE7;&#xE3;o.</p><p>Observe que n&#xE3;o h&#xE1; mais convers&#xE3;o de <code>.env.erb</code> ou <code>kamal push env</code>. Todos foram removidos.</p><h3 id="8-verificar-novamente-sua-configura%C3%A7%C3%A3o">8. Verificar novamente sua configura&#xE7;&#xE3;o</h3><p>Verifique sua nova configura&#xE7;&#xE3;o executando o comando <code>kamal config</code>:</p><pre><code class="language-bash">$ kamal config
</code></pre><p>Se voc&#xEA; estava usando redes Docker personalizadas para comunica&#xE7;&#xE3;o de acess&#xF3;rios, n&#xE3;o as remova ainda. Somente se voc&#xEA; as nomeou como <code>kamal</code>, remova-as da configura&#xE7;&#xE3;o para evitar conflitos.</p><h3 id="9-executar-a-atualiza%C3%A7%C3%A3o-in-place">9. Executar a atualiza&#xE7;&#xE3;o in-place</h3><p>Fa&#xE7;a o primeiro deploy do Kamal 2 executando uma atualiza&#xE7;&#xE3;o:</p><pre><code class="language-bash">$ kamal upgrade
</code></pre><p>Isso far&#xE1; v&#xE1;rias coisas, como remover o Traefik, criar a rede Docker do Kamal, alternar para o Kamal Proxy, reiniciar a aplica&#xE7;&#xE3;o e, finalmente, reiniciar os acess&#xF3;rios.</p><h3 id="10-remover-redes-docker-personalizadas">10. Remover redes Docker personalizadas</h3><p>Agora voc&#xEA; pode remover sua rede Docker personalizada, pois tudo pode ser executado com a nova rede do Kamal.</p><p>Voc&#xEA; pode reiniciar sua aplica&#xE7;&#xE3;o e acess&#xF3;rios para aplicar essa &#xFA;ltima mudan&#xE7;a:</p><pre><code class="language-bash">$ kamal deploy
$ kamal accessory reboot [ACCESSORY]
</code></pre><h3 id="11-corrigir-falhas-na-atualiza%C3%A7%C3%A3o">11. Corrigir falhas na atualiza&#xE7;&#xE3;o</h3><p>Lembre-se de que, se a atualiza&#xE7;&#xE3;o substituir o proxy, mas falhar posteriormente, voc&#xEA; pode corrigir o problema subjacente e continuar fazendo o redeploy da aplica&#xE7;&#xE3;o ou reiniciando os acess&#xF3;rios.</p>]]></content:encoded></item><item><title><![CDATA[20 Truques de Linha de Comando do Git que Todo Desenvolvedor Deveria Saber]]></title><description><![CDATA[<p>O Git &#xE9; uma ferramenta essencial de controle de vers&#xE3;o para desenvolvedores. Embora ferramentas GUI possam simplificar algumas tarefas, dominar a linha de comando do Git oferece um controle mais profundo, flexibilidade e velocidade. Aqui est&#xE3;o 20 truques de linha de comando do Git que todo</p>]]></description><link>https://jcmaciel.com/20-truques-de-linha-de-comando-do-git-que-todo-desenvolvedor-deveria-saber/</link><guid isPermaLink="false">6717a2cf18f08500018391b1</guid><category><![CDATA[Programação]]></category><category><![CDATA[Engenharia de Software]]></category><category><![CDATA[Git]]></category><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Tue, 22 Oct 2024 13:06:34 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1618401471353-b98afee0b2eb?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGdpdHxlbnwwfHx8fDE3Mjk2MDIzNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1618401471353-b98afee0b2eb?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGdpdHxlbnwwfHx8fDE3Mjk2MDIzNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="20 Truques de Linha de Comando do Git que Todo Desenvolvedor Deveria Saber"><p>O Git &#xE9; uma ferramenta essencial de controle de vers&#xE3;o para desenvolvedores. Embora ferramentas GUI possam simplificar algumas tarefas, dominar a linha de comando do Git oferece um controle mais profundo, flexibilidade e velocidade. Aqui est&#xE3;o 20 truques de linha de comando do Git que todo desenvolvedor deve conhecer para otimizar seu fluxo de trabalho.</p><p><strong>Resetar um Arquivo para o &#xDA;ltimo Commit</strong><br>Descarte as altera&#xE7;&#xF5;es locais em um arquivo espec&#xED;fico.</p><pre><code class="language-bash">git checkout -- path/to/file
</code></pre><p><strong>Responsabilizar uma Linha de C&#xF3;digo</strong><br>Descubra quem escreveu uma linha espec&#xED;fica em um arquivo.</p><pre><code class="language-bash">git blame path/to/file
</code></pre><p><strong>Buscar Apenas Metadados</strong><br>Quer evitar baixar todo o reposit&#xF3;rio?</p><pre><code class="language-bash">git fetch --dry-run
</code></pre><p>Isso permite ver o que seria buscado sem realmente baixar os dados.</p><p><strong>Reverter um Commit J&#xE1; Enviado</strong><br>Desfa&#xE7;a as altera&#xE7;&#xF5;es de um commit espec&#xED;fico sem alterar o hist&#xF3;rico.</p><pre><code class="language-bash">git revert &lt;commit-hash&gt;
</code></pre><p><strong>Editar o .gitignore Ap&#xF3;s Fazer Commit</strong><br>Se esqueceu de ignorar certos arquivos, atualize o <code>.gitignore</code>.</p><pre><code class="language-bash">echo &quot;node_modules/&quot; &gt;&gt; .gitignore
git rm -r --cached node_modules/
git commit -m &quot;Atualizar .gitignore&quot;
</code></pre><p><strong>Visualizar o Arquivo em um Commit Espec&#xED;fico</strong><br>Veja o estado de um arquivo em um commit espec&#xED;fico.</p><pre><code class="language-bash">git show &lt;commit-hash&gt;:path/to/file
</code></pre><p><strong>Combinar Commits com Rebase Interativo</strong><br>Combine v&#xE1;rios commits em um s&#xF3;.</p><pre><code class="language-bash">git rebase -i HEAD~n  # Substitua &apos;n&apos; pelo n&#xFA;mero de commits
</code></pre><p><strong>Rastrear um Branch Upstream</strong><br>Mantenha seu branch local em sincroniza&#xE7;&#xE3;o com um branch remoto.</p><pre><code class="language-bash">git branch --set-upstream-to=origin/main
</code></pre><p><strong>Limpar Arquivos e Diret&#xF3;rios N&#xE3;o Rastre&#xE1;veis</strong><br>Remova rapidamente arquivos indesejados que n&#xE3;o s&#xE3;o rastreados pelo Git.</p><pre><code class="language-bash">git clean -fd
</code></pre><p>&#x1F4A1; Use <code>-n</code> para uma simula&#xE7;&#xE3;o antes de remover de fato.</p><p><strong>Listar Todos os Branches (Locais e Remotos)</strong><br>Veja quais branches est&#xE3;o dispon&#xED;veis.</p><pre><code class="language-bash">git branch -a
</code></pre><p><strong>Cherry-Pick de Commits Espec&#xED;ficos</strong><br>Quer trazer um commit espec&#xED;fico de outro branch?</p><pre><code class="language-bash">git cherry-pick &lt;commit-hash&gt;
</code></pre><p><strong>Rebase para um Hist&#xF3;rico de Commits Limpo</strong><br>O rebase reescreve o hist&#xF3;rico de commits para maior clareza.</p><pre><code class="language-bash">git rebase -i HEAD~3
</code></pre><p>Isso permite editar, combinar ou reordenar seus &#xFA;ltimos 3 commits.</p><p><strong>Encontrar um Bug com Bisect</strong><br>Use <code>git bisect</code> para encontrar o commit que introduziu um bug.</p><pre><code class="language-bash">git bisect start
git bisect bad  # O commit atual est&#xE1; com problema
git bisect good &lt;commit-hash&gt;  # Um commit conhecido como bom
</code></pre><p>O Git percorrer&#xE1; o hist&#xF3;rico de commits para identificar o commit problem&#xE1;tico.</p><p><strong>Verificar Diferen&#xE7;as nas Altera&#xE7;&#xF5;es em Est&#xE1;gio</strong><br>Use <code>git diff</code> para comparar arquivos em diferentes est&#xE1;gios.</p><pre><code class="language-bash">git diff --staged
</code></pre><p>Isso mostra as altera&#xE7;&#xF5;es que est&#xE3;o em est&#xE1;gio, mas ainda n&#xE3;o foram commitadas.</p><p><strong>Alterar o Autor do Commit</strong><br>Mude o autor do &#xFA;ltimo commit.</p><pre><code class="language-bash">git commit --amend --author=&quot;Novo Autor &lt;novautor@exemplo.com&gt;&quot;
</code></pre><p><strong>Visualizar o Hist&#xF3;rico de Commits Graficamente</strong><br>Visualizar o hist&#xF3;rico de commits facilita entender o estado do projeto.</p><pre><code class="language-bash">git log --graph --oneline --all
</code></pre><p><strong>Guardar Altera&#xE7;&#xF5;es N&#xE3;o Cometidas</strong><br>Precisa mudar rapidamente de branch sem fazer commit?</p><pre><code class="language-bash">git stash
</code></pre><p>&#x1F4A1; Recupere o stash mais tarde com:</p><pre><code class="language-bash">git stash pop
</code></pre><p><strong>Emendar o &#xDA;ltimo Commit</strong><br>Esqueceu de incluir uma altera&#xE7;&#xE3;o ou deseja atualizar a mensagem do commit?</p><pre><code class="language-bash">git add .
git commit --amend -m &quot;Mensagem de commit atualizada&quot;
</code></pre><p>Isso atualiza o commit anterior sem criar um novo.</p><p><strong>Desfazer o &#xDA;ltimo Commit (sem perder altera&#xE7;&#xF5;es)</strong><br>Se voc&#xEA; cometeu um erro no &#xFA;ltimo commit, pode desfaz&#xEA;-lo.</p><pre><code class="language-bash">git reset --soft HEAD~1
</code></pre><p>Isso deixa suas altera&#xE7;&#xF5;es em est&#xE1;gio, permitindo emendar o commit ou corrigir o problema.</p><p><strong>Configurar Configura&#xE7;&#xE3;o Global</strong><br>Garanta que seus commits estejam vinculados &#xE0; identidade correta.</p><pre><code class="language-bash">git config --global user.name &quot;Seu Nome&quot;
git config --global user.email &quot;voce@exemplo.com&quot;
</code></pre><p>&#x1F4A1; Dica: Use <code>--local</code> em vez de <code>--global</code> para definir configura&#xE7;&#xF5;es espec&#xED;ficas do projeto.</p><p>Esses 20 truques de linha de comando do Git podem tornar seu processo de desenvolvimento mais suave, seja voc&#xEA; trabalhando sozinho ou em equipe. Embora ferramentas GUI ofere&#xE7;am conveni&#xEA;ncia, dominar a linha de comando do Git proporciona mais controle sobre seus fluxos de trabalho. Experimente esses comandos e aprimore suas habilidades no Git!</p>]]></content:encoded></item><item><title><![CDATA[Recuperando a Primeira Ocorrência de Forma Eficiente: pick vs pluck no Rails]]></title><description><![CDATA[<p>No desenvolvimento com Ruby on Rails, frequentemente precisamos buscar dados espec&#xED;ficos diretamente do banco de dados. Dois m&#xE9;todos comuns usados para isso s&#xE3;o <code>pick</code> e <code>pluck</code>. Embora ambos sejam &#xFA;teis para extrair dados, eles servem a prop&#xF3;sitos diferentes, e &#xE9; importante</p>]]></description><link>https://jcmaciel.com/recuperando-a-primeira-ocorrencia-de-forma-eficiente-pick-vs-pluck-no-rails/</link><guid isPermaLink="false">66fef296e60ca600013e0020</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:38:10 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1603969409447-ba86143a03f6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGZhc3QlMjBwY3xlbnwwfHx8fDE3Mjc5ODQzMjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1603969409447-ba86143a03f6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGZhc3QlMjBwY3xlbnwwfHx8fDE3Mjc5ODQzMjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Recuperando a Primeira Ocorr&#xEA;ncia de Forma Eficiente: pick vs pluck no Rails"><p>No desenvolvimento com Ruby on Rails, frequentemente precisamos buscar dados espec&#xED;ficos diretamente do banco de dados. Dois m&#xE9;todos comuns usados para isso s&#xE3;o <code>pick</code> e <code>pluck</code>. Embora ambos sejam &#xFA;teis para extrair dados, eles servem a prop&#xF3;sitos diferentes, e &#xE9; importante saber quando usar cada um para otimizar o desempenho da sua aplica&#xE7;&#xE3;o.</p>
<h3 id="pluck-extraindo-m%C3%BAltiplos-valores"><code>pluck</code>: Extraindo M&#xFA;ltiplos Valores</h3>
<p>O m&#xE9;todo <code>pluck</code> &#xE9; ideal quando voc&#xEA; deseja extrair os valores de um ou mais atributos de todos os registros que correspondem a uma consulta. Ele constr&#xF3;i uma consulta SQL que retorna apenas os campos especificados, o que pode melhorar o desempenho ao evitar o carregamento de objetos ActiveRecord desnecess&#xE1;rios.</p>
<h4 id="exemplo-de-uso">Exemplo de Uso:</h4>
<pre><code class="language-ruby"># Extraindo os nomes de todos os usu&#xE1;rios
User.pluck(:name)
# Isso retornar&#xE1; algo como:
# [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;]
</code></pre>
<p>No exemplo acima, <code>pluck</code> retorna um array contendo os valores do atributo <code>name</code> de todos os usu&#xE1;rios na tabela.</p>
<h3 id="pick-buscando-o-valor-da-primeira-linha"><code>pick</code>: Buscando o Valor da Primeira Linha</h3>
<p>O m&#xE9;todo <code>pick</code> &#xE9; mais adequado quando voc&#xEA; precisa apenas do valor de um &#xFA;nico atributo da primeira linha que corresponde a uma consulta. Usar <code>pick</code> &#xE9; mais eficiente do que usar <code>pluck</code> seguido de <code>first</code>, pois <code>pick</code> executa uma consulta SQL que retorna diretamente o valor desejado sem a necessidade de carregar objetos adicionais na mem&#xF3;ria.</p>
<h4 id="exemplo-de-uso-1">Exemplo de Uso:</h4>
<pre><code class="language-ruby"># Buscando o nome do primeiro usu&#xE1;rio ativo encontrado
User.where(active: true).pick(:name)
# Isso retornar&#xE1; algo como:
# &quot;Alice&quot;
</code></pre>
<h3 id="por-que-pick-%C3%A9-melhor-que-pluckfirst">Por Que <code>pick</code> &#xE9; Melhor que <code>pluck.first</code>?</h3>
<p>Considere uma situa&#xE7;&#xE3;o onde voc&#xEA; precisa do valor do primeiro registro. A abordagem comum poderia ser:</p>
<pre><code class="language-ruby"># Usando pluck seguido de first
User.where(active: true).pluck(:name).first
</code></pre>
<p>Embora isso funcione, ele executa duas opera&#xE7;&#xF5;es: primeiro, extrai todos os nomes dos usu&#xE1;rios ativos, e depois pega o primeiro valor do array resultante. Isso significa que voc&#xEA; est&#xE1; potencialmente carregando muito mais dados do que precisa, especialmente se houver muitos usu&#xE1;rios ativos.</p>
<p>Por outro lado, com <code>pick</code>, voc&#xEA; faz isso de forma mais direta e eficiente:</p>
<pre><code class="language-ruby"># Usando pick para obter o nome do primeiro usu&#xE1;rio ativo
User.where(active: true).pick(:name)
</code></pre>
<p>Aqui, a consulta SQL retornar&#xE1; apenas o valor do atributo <code>name</code> do primeiro usu&#xE1;rio ativo encontrado, sem carregar dados adicionais.</p>
<h3 id="resumo">Resumo</h3>
<ul><li><strong><code>pluck</code></strong>: Use para extrair os valores de um ou mais atributos de todos os registros que correspondem a uma consulta.</li><li><strong><code>pick</code></strong>: Use para obter o valor de um &#xFA;nico atributo da primeira linha encontrada pela consulta.</li></ul>
<h3 id="benef%C3%ADcios-de-usar-pick">Benef&#xED;cios de Usar <code>pick</code>:</h3>
<ul><li><strong>Efici&#xEA;ncia</strong>: Executa uma &#xFA;nica consulta SQL retornando apenas o valor necess&#xE1;rio.</li><li><strong>Desempenho</strong>: Evita o carregamento de objetos ActiveRecord desnecess&#xE1;rios na mem&#xF3;ria.</li><li><strong>Simplicidade</strong>: C&#xF3;digo mais limpo e direto para buscar o valor da primeira linha.</li></ul>
<p>Ao entender as diferen&#xE7;as e saber quando usar cada m&#xE9;todo, voc&#xEA; pode melhorar significativamente o desempenho e a efici&#xEA;ncia das suas consultas no Rails. Aproveite o poder desses m&#xE9;todos para construir aplica&#xE7;&#xF5;es mais r&#xE1;pidas e otimizadas!</p>]]></content:encoded></item><item><title><![CDATA[Definindo Versões Mínimas de Navegadores com allow_browser no Rails de Forma Eficiente]]></title><description><![CDATA[<p>O Rails 8.0 introduz um recurso poderoso chamado <code>allow_browser</code>, que permite aos desenvolvedores especificar vers&#xF5;es m&#xED;nimas de navegadores para suas aplica&#xE7;&#xF5;es. Essa funcionalidade oferece v&#xE1;rias vantagens significativas que valem a pena considerar.</p>
<p>Ao impor vers&#xF5;es m&#xED;</p>]]></description><link>https://jcmaciel.com/definindo-versoes-minimas-de-navegadores-com-allow_browser-no-rails-de-forma-eficiente/</link><guid isPermaLink="false">66fef22ae60ca600013e0014</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:36:42 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1655196601100-8bfb26cf99e9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGludGVybmV0JTIwZXhwbG9yZXJ8ZW58MHx8fHwxNzI3OTg0MTkxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1655196601100-8bfb26cf99e9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGludGVybmV0JTIwZXhwbG9yZXJ8ZW58MHx8fHwxNzI3OTg0MTkxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Definindo Vers&#xF5;es M&#xED;nimas de Navegadores com allow_browser no Rails de Forma Eficiente"><p>O Rails 8.0 introduz um recurso poderoso chamado <code>allow_browser</code>, que permite aos desenvolvedores especificar vers&#xF5;es m&#xED;nimas de navegadores para suas aplica&#xE7;&#xF5;es. Essa funcionalidade oferece v&#xE1;rias vantagens significativas que valem a pena considerar.</p>
<p>Ao impor vers&#xF5;es m&#xED;nimas de navegadores, voc&#xEA; mitiga vulnerabilidades de seguran&#xE7;a n&#xE3;o resolvidas, melhora a efici&#xEA;ncia operacional e garante compatibilidade cont&#xED;nua com as funcionalidades modernas da web. Essa abordagem protege os dados dos usu&#xE1;rios com patches de seguran&#xE7;a atualizados, otimiza o desempenho e promove uma experi&#xEA;ncia unificada para todos os usu&#xE1;rios da sua aplica&#xE7;&#xE3;o. Al&#xE9;m disso, ao especificar uma vers&#xE3;o m&#xED;nima de navegador, os desenvolvedores podem priorizar o uso de tecnologias modernas, simplificando o fluxo de trabalho de desenvolvimento e minimizando as tarefas de manuten&#xE7;&#xE3;o cont&#xED;nua.</p>
<h3 id="implementando-allowbrowser-no-rails-80">Implementando <code>allow_browser</code> no Rails 8.0</h3>
<p>Com o Rails 8.0, definir as vers&#xF5;es m&#xED;nimas de navegadores &#xE9; simples, utilizando o m&#xE9;todo <code>allow_browser</code> no <code>ApplicationController</code>. Veja como implement&#xE1;-lo:</p>
<h3 id="configura%C3%A7%C3%A3o-b%C3%A1sica">Configura&#xE7;&#xE3;o B&#xE1;sica</h3>
<p>Para especificar as vers&#xF5;es m&#xED;nimas de navegadores suportadas, inclua o m&#xE9;todo <code>allow_browser</code> no seu <code>ApplicationController</code>:</p>
<pre><code class="language-ruby">class ApplicationController &lt; ActionController::Base
  allow_browser versions: :modern
end
</code></pre>
<p>Usar a configura&#xE7;&#xE3;o <code>:modern</code> garante a compatibilidade apenas com navegadores que possuem suporte embutido para recursos como imagens <code>webp</code>, notifica&#xE7;&#xF5;es web push, badges, import maps, nesting CSS e o seletor CSS <code>:has</code>.</p>
<h3 id="configura%C3%A7%C3%A3o-personalizada">Configura&#xE7;&#xE3;o Personalizada</h3>
<p>Se preferir especificar vers&#xF5;es m&#xED;nimas para navegadores individuais, voc&#xEA; pode personaliz&#xE1;-la da seguinte maneira:</p>
<pre><code class="language-ruby">class ApplicationController &lt; ActionController::Base
  allow_browser versions: { edge: 88, chrome: 90, opera: 75 }
end
</code></pre>
<p>Essa configura&#xE7;&#xE3;o permite todas as vers&#xF5;es de Safari e Firefox, mas restringe o suporte ao Edge 88+, Chrome 90+ e Opera 75+.</p>
<h3 id="desativando-navegadores-espec%C3%ADficos">Desativando Navegadores Espec&#xED;ficos</h3>
<p>Voc&#xEA; tamb&#xE9;m pode desativar o suporte para determinados navegadores, se necess&#xE1;rio. Por exemplo, para desativar o Firefox:</p>
<pre><code class="language-ruby">class ApplicationController &lt; ActionController::Base
  allow_browser versions: { safari: 20, firefox: false, ie: 9 }
end
</code></pre>
<p>Adicionar <code>allow_browser</code> ao <code>ApplicationController</code> aplica essa configura&#xE7;&#xE3;o globalmente a todas as a&#xE7;&#xF5;es. No entanto, voc&#xEA; pode restringi-la a a&#xE7;&#xF5;es espec&#xED;ficas usando as op&#xE7;&#xF5;es <code>only</code> ou <code>except</code>.</p>
<h3 id="restringindo-a-a%C3%A7%C3%B5es-espec%C3%ADficas">Restringindo a A&#xE7;&#xF5;es Espec&#xED;ficas</h3>
<p>Para aplicar essa configura&#xE7;&#xE3;o a a&#xE7;&#xF5;es espec&#xED;ficas do controlador, use:</p>
<pre><code class="language-ruby">class ChatController &lt; ApplicationController
  allow_browser versions: { chrome: 85, opera: false, ie: 9 }, only: :show
end
</code></pre>
<p>Nesse exemplo, a a&#xE7;&#xE3;o <code>show</code> do <code>ChatController</code> verifica se a vers&#xE3;o do Chrome &#xE9; pelo menos 85 e se a vers&#xE3;o do Opera &#xE9; pelo menos 9. A a&#xE7;&#xE3;o <code>show</code> n&#xE3;o oferece suporte ao Opera.</p>
<h3 id="p%C3%A1gina-personalizada-para-navegadores-n%C3%A3o-suportados">P&#xE1;gina Personalizada para Navegadores N&#xE3;o Suportados</h3>
<p>Navegadores n&#xE3;o suportados ser&#xE3;o redirecionados para uma p&#xE1;gina personalizada (426.html) que explica a necessidade de atualizar o navegador. O c&#xF3;digo de status HTTP ser&#xE1; <code>426 Upgrade Required</code>.</p>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>O uso do <code>allow_browser</code> no Rails 8.0 facilita a defini&#xE7;&#xE3;o de vers&#xF5;es m&#xED;nimas de navegadores, permitindo que sua aplica&#xE7;&#xE3;o funcione com seguran&#xE7;a e efici&#xEA;ncia nas plataformas mais modernas, enquanto reduz a carga de manuten&#xE7;&#xE3;o e oferece uma experi&#xEA;ncia de usu&#xE1;rio mais consistente.</p>]]></content:encoded></item><item><title><![CDATA[Entendendo as Diferenças Entre os Métodos any?, exists? e present? do ActiveRecord]]></title><description><![CDATA[<p>O ActiveRecord, a camada ORM (Object-Relational Mapping) do Ruby on Rails, fornece v&#xE1;rios m&#xE9;todos para consultar seu banco de dados. Entre esses m&#xE9;todos est&#xE3;o <code>any?</code>, <code>exists?</code> e <code>present?</code>, cada um com suas nuances e casos de uso espec&#xED;ficos. Compreender as</p>]]></description><link>https://jcmaciel.com/entendendo-as-diferencas-entre-os-metodos-any-exists-e-present-do-activerecord/</link><guid isPermaLink="false">66fef1c5e60ca600013e0008</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:34:56 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1667372459470-5f61c93c6d3f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxkYXRhYmFzZXxlbnwwfHx8fDE3Mjc5ODM2MDR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1667372459470-5f61c93c6d3f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxkYXRhYmFzZXxlbnwwfHx8fDE3Mjc5ODM2MDR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Entendendo as Diferen&#xE7;as Entre os M&#xE9;todos any?, exists? e present? do ActiveRecord"><p>O ActiveRecord, a camada ORM (Object-Relational Mapping) do Ruby on Rails, fornece v&#xE1;rios m&#xE9;todos para consultar seu banco de dados. Entre esses m&#xE9;todos est&#xE3;o <code>any?</code>, <code>exists?</code> e <code>present?</code>, cada um com suas nuances e casos de uso espec&#xED;ficos. Compreender as diferen&#xE7;as entre esses m&#xE9;todos pode ajudar voc&#xEA; a escrever um c&#xF3;digo mais eficiente e leg&#xED;vel. Neste post, vamos explorar esses m&#xE9;todos, suas diferen&#xE7;as e fornecer exemplos para ilustrar como funcionam no n&#xED;vel do banco de dados.</p>
<h3 id="any"><code>any?</code></h3>
<p>O m&#xE9;todo <code>any?</code> verifica se h&#xE1; registros em uma cole&#xE7;&#xE3;o que satisfa&#xE7;am uma determinada condi&#xE7;&#xE3;o. Ele dispara uma consulta SQL para determinar se h&#xE1; registros, mas n&#xE3;o carrega os registros na mem&#xF3;ria.</p>
<h4 id="exemplo">Exemplo:</h4>
<p>Vamos considerar um modelo <code>User</code> para ilustrar o <code>any?</code>:</p>
<pre><code class="language-ruby"># Verificando se h&#xE1; usu&#xE1;rios no banco de dados
User.any?
# SQL Query:
# SELECT 1 AS one FROM users LIMIT 1;

# Verificando se h&#xE1; usu&#xE1;rios com mais de 18 anos
User.where(&apos;age &gt; 18&apos;).any?
# SQL Query:
# SELECT 1 AS one FROM users WHERE (age &gt; 18) LIMIT 1;
</code></pre>
<h4 id="detalhes-no-n%C3%ADvel-do-banco-de-dados">Detalhes no N&#xED;vel do Banco de Dados:</h4>
<p>O uso de <code>any?</code> sem um bloco gera uma consulta SQL com <code>LIMIT 1</code> para verificar se pelo menos um registro existe. Isso &#xE9; eficiente porque n&#xE3;o carrega todos os registros na mem&#xF3;ria.</p>
<h3 id="exists"><code>exists?</code></h3>
<p>O m&#xE9;todo <code>exists?</code> verifica se existe algum registro que corresponda a uma condi&#xE7;&#xE3;o dada. Esse m&#xE9;todo &#xE9; eficiente porque executa uma consulta <code>SELECT 1 AS one</code>, que &#xE9; r&#xE1;pida e n&#xE3;o carrega os registros reais na mem&#xF3;ria.</p>
<h4 id="exemplo-1">Exemplo:</h4>
<p>Usando novamente o modelo <code>User</code> para ilustrar o <code>exists?</code>:</p>
<pre><code class="language-ruby"># Verificando se existe algum usu&#xE1;rio no banco de dados
User.exists?
# SQL Query:
# SELECT 1 AS one FROM users LIMIT 1;

# Verificando se existe algum usu&#xE1;rio com o nome &quot;John&quot;
User.exists?(name: &apos;John&apos;)
# SQL Query:
# SELECT 1 AS one FROM users WHERE users.name = &apos;John&apos; LIMIT 1;
</code></pre>
<h4 id="detalhes-no-n%C3%ADvel-do-banco-de-dados-1">Detalhes no N&#xED;vel do Banco de Dados:</h4>
<p>O m&#xE9;todo <code>exists?</code> executa uma consulta leve, verificando apenas a exist&#xEA;ncia de registros, e n&#xE3;o carrega todas as colunas do registro, apenas um valor para determinar a exist&#xEA;ncia.</p>
<h3 id="present"><code>present?</code></h3>
<p>O m&#xE9;todo <code>present?</code> n&#xE3;o &#xE9; espec&#xED;fico do ActiveRecord; &#xE9; uma extens&#xE3;o do Rails dispon&#xED;vel para todos os objetos. Ele retorna <code>true</code> se o objeto n&#xE3;o for <code>blank?</code>. Para cole&#xE7;&#xF5;es, isso significa que ele verifica se a cole&#xE7;&#xE3;o n&#xE3;o est&#xE1; vazia.</p>
<h4 id="exemplo-2">Exemplo:</h4>
<p>Usando o modelo <code>User</code> para ilustrar o <code>present?</code>:</p>
<pre><code class="language-ruby"># Verificando se a cole&#xE7;&#xE3;o de todos os usu&#xE1;rios est&#xE1; presente (ou seja, n&#xE3;o vazia)
User.all.present?
# SQL Query:
# SELECT users.* FROM users;
# O Ruby carrega todos os registros e verifica se a cole&#xE7;&#xE3;o n&#xE3;o est&#xE1; vazia

# Buscando usu&#xE1;rios com mais de 18 anos e verificando se o resultado est&#xE1; presente
users = User.where(&apos;age &gt; 18&apos;)
users.present?
# SQL Query:
# SELECT users.* FROM users WHERE (age &gt; 18);
# O Ruby carrega os registros correspondentes e verifica se a cole&#xE7;&#xE3;o n&#xE3;o est&#xE1; vazia
</code></pre>
<h4 id="detalhes-no-n%C3%ADvel-do-banco-de-dados-2">Detalhes no N&#xED;vel do Banco de Dados:</h4>
<p>Usar <code>present?</code> ap&#xF3;s uma consulta carregar&#xE1; os registros correspondentes na mem&#xF3;ria e depois verificar&#xE1; se a cole&#xE7;&#xE3;o n&#xE3;o est&#xE1; vazia. Isso pode ser menos eficiente se voc&#xEA; s&#xF3; precisar verificar a presen&#xE7;a de registros, pois todos os registros correspondentes ser&#xE3;o carregados.</p>
<h3 id="diferen%C3%A7as-chave">Diferen&#xE7;as-Chave</h3>
<h4 id="desempenho">Desempenho:</h4>
<ul><li><code>any?</code> e <code>exists?</code> realizam consultas leves, mas <code>exists?</code> &#xE9; geralmente preferido para verificar a exist&#xEA;ncia sem carregar registros.</li><li><code>present?</code> verifica se uma cole&#xE7;&#xE3;o n&#xE3;o est&#xE1; vazia, mas carrega todos os registros na mem&#xF3;ria ap&#xF3;s uma consulta.</li></ul>
<h4 id="casos-de-uso">Casos de Uso:</h4>
<ul><li>Use <code>any?</code> quando precisar verificar se h&#xE1; algum registro existente em um escopo.</li><li>Use <code>exists?</code> para uma verifica&#xE7;&#xE3;o r&#xE1;pida se algum registro corresponde a uma condi&#xE7;&#xE3;o.</li><li>Use <code>present?</code> para verificar se uma cole&#xE7;&#xE3;o ou resultado de consulta n&#xE3;o est&#xE1; vazio.</li></ul>
<h3 id="resumo">Resumo</h3>
<p>Compreender quando e como usar <code>any?</code>, <code>exists?</code> e <code>present?</code> pode impactar significativamente o desempenho e a legibilidade de suas aplica&#xE7;&#xF5;es Rails. Ao escolher o m&#xE9;todo certo para o cen&#xE1;rio correto, voc&#xEA; pode garantir que seu c&#xF3;digo seja tanto eficiente quanto expressivo.</p>
<p>Aqui est&#xE1; um resumo r&#xE1;pido dos exemplos para cada m&#xE9;todo, mostrando suas consultas SQL correspondentes:</p>
<h4 id="any-1"><code>any?</code>:</h4>
<pre><code class="language-ruby">User.any?
# SQL: SELECT 1 AS one FROM users LIMIT 1;
  
User.where(&apos;age &gt; 18&apos;).any?
# SQL: SELECT 1 AS one FROM users WHERE (age &gt; 18) LIMIT 1;
</code></pre>
<h4 id="exists-1"><code>exists?</code>:</h4>
<pre><code class="language-ruby">User.exists?
# SQL: SELECT 1 AS one FROM users LIMIT 1;
  
User.exists?(name: &apos;John&apos;)
# SQL: SELECT 1 AS one FROM users WHERE users.name = &apos;John&apos; LIMIT 1;
</code></pre>
<h4 id="present-1"><code>present?</code>:</h4>
<pre><code class="language-ruby">User.all.present?
# SQL: SELECT users.* FROM users;
  
users = User.where(&apos;age &gt; 18&apos;)
users.present?
# SQL: SELECT users.* FROM users WHERE (age &gt; 18);
</code></pre>
<p>Usando esses m&#xE9;todos de forma apropriada, voc&#xEA; pode tornar suas aplica&#xE7;&#xF5;es Rails mais eficientes e seu c&#xF3;digo mais leg&#xED;vel.</p>]]></content:encoded></item><item><title><![CDATA[Criando Colunas Virtuais no Rails 7: Um Guia Passo a Passo]]></title><description><![CDATA[<p><br>O Rails 7 traz uma s&#xE9;rie de novos recursos e melhorias, tornando ainda mais f&#xE1;cil construir aplica&#xE7;&#xF5;es web robustas e de f&#xE1;cil manuten&#xE7;&#xE3;o. Um dos recursos poderosos dispon&#xED;veis no Rails &#xE9; a capacidade de criar colunas</p>]]></description><link>https://jcmaciel.com/criando-colunas-virtuais-no-rails-7-um-guia-passo-a-passo/</link><guid isPermaLink="false">66fef141e60ca600013dfffc</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:32:36 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1544383835-bda2bc66a55d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGRhdGFiYXNlfGVufDB8fHx8MTcyNzk4MzYwNHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1544383835-bda2bc66a55d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGRhdGFiYXNlfGVufDB8fHx8MTcyNzk4MzYwNHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Criando Colunas Virtuais no Rails 7: Um Guia Passo a Passo"><p><br>O Rails 7 traz uma s&#xE9;rie de novos recursos e melhorias, tornando ainda mais f&#xE1;cil construir aplica&#xE7;&#xF5;es web robustas e de f&#xE1;cil manuten&#xE7;&#xE3;o. Um dos recursos poderosos dispon&#xED;veis no Rails &#xE9; a capacidade de criar colunas virtuais (ou computadas/geradas) nas tabelas do banco de dados. Neste post, exploraremos como criar uma coluna virtual no Rails 7, com explica&#xE7;&#xF5;es detalhadas e exemplos.</p>
<h3 id="o-que-s%C3%A3o-colunas-virtuais">O que s&#xE3;o Colunas Virtuais?</h3>
<p>Colunas virtuais s&#xE3;o colunas do banco de dados que n&#xE3;o s&#xE3;o diretamente armazenadas, mas sim calculadas com base em express&#xF5;es que envolvem outras colunas. Elas podem ser particularmente &#xFA;teis para dados derivados, como concatena&#xE7;&#xF5;es, c&#xE1;lculos ou transforma&#xE7;&#xF5;es que precisam estar sempre consistentes com os dados de origem.</p>
<h3 id="exemplo-de-cen%C3%A1rio">Exemplo de Cen&#xE1;rio</h3>
<p>Suponha que temos uma tabela <code>PersonalDocuments</code> e queremos adicionar uma coluna <code>full_name</code> que armazena o nome completo de uma pessoa, al&#xE9;m de uma coluna virtual <code>full_name_length</code> que calcula o comprimento do nome completo.</p>
<h3 id="criando-a-migration">Criando a Migration</h3>
<p>Para criar a tabela <code>PersonalDocuments</code> com as colunas necess&#xE1;rias, usaremos o m&#xE9;todo de <em>migration</em> <code>create_table</code>. Veja como fazer isso:</p>
<h4 id="migration">Migration</h4>
<pre><code class="language-ruby">class CreatePersonalDocuments &lt; ActiveRecord::Migration[7.0]
  def change
    create_table :personal_documents do |t|
      t.string :full_name
      t.virtual :full_name_length, type: :integer, as: &quot;length(full_name)&quot;, stored: true

      t.timestamps
    end
  end
end
</code></pre>
<p><strong>Explicando o c&#xF3;digo:</strong></p>
<ul><li><code>create_table :personal_documents</code>: Cria uma nova tabela chamada <code>personal_documents</code>.</li><li><code>t.string :full_name</code>: Adiciona uma coluna <code>full_name</code> &#xE0; tabela.</li><li><code>t.virtual :full_name_length, type: :integer, as: &quot;length(full_name)&quot;, stored: true</code>: Adiciona uma coluna virtual <code>full_name_length</code> que calcula o comprimento da coluna <code>full_name</code>.</li><li>A op&#xE7;&#xE3;o <code>stored: true</code> garante que o valor de <code>full_name_length</code> seja calculado quando a linha for inserida ou atualizada, sendo armazenado no banco de dados. Isso torna as consultas mais eficientes, pois o valor n&#xE3;o precisa ser recalculado toda vez que for acessado.</li></ul>
<h3 id="atualizando-o-modelo">Atualizando o Modelo</h3>
<p>No seu modelo <code>PersonalDocument</code>, n&#xE3;o &#xE9; necess&#xE1;ria nenhuma configura&#xE7;&#xE3;o especial para a coluna virtual. Ela estar&#xE1; dispon&#xED;vel como um atributo de leitura.</p>
<h4 id="modelo">Modelo</h4>
<pre><code class="language-ruby">class PersonalDocument &lt; ApplicationRecord
  # Qualquer outra l&#xF3;gica do modelo
end
</code></pre>
<h3 id="usando-a-coluna-virtual">Usando a Coluna Virtual</h3>
<p>Agora voc&#xEA; pode usar a coluna virtual <code>full_name_length</code> como qualquer outro atributo. Aqui est&#xE1; um exemplo de como criar um registro e acessar a coluna virtual:</p>
<h4 id="exemplo-de-uso">Exemplo de Uso</h4>
<pre><code class="language-ruby">personal_document = PersonalDocument.create(full_name: &quot;John Doe&quot;)
puts personal_document.full_name_length  # Sa&#xED;da: 8
</code></pre>
<h3 id="considera%C3%A7%C3%B5es-importantes">Considera&#xE7;&#xF5;es Importantes</h3>
<ul><li><strong>Armazenado vs. Virtual:</strong> A op&#xE7;&#xE3;o <code>stored: true</code> faz com que a coluna seja uma &quot;coluna gerada armazenada&quot;, o que significa que seu valor &#xE9; calculado quando a linha &#xE9; inserida ou atualizada, e armazenado no banco de dados. Se voc&#xEA; quiser que o valor seja recalculado sempre que for acessado, pode usar <code>stored: false</code> (embora o suporte para isso varie entre os bancos de dados).</li></ul>
<h3 id="verificando-a-configura%C3%A7%C3%A3o">Verificando a Configura&#xE7;&#xE3;o</h3>
<p>Ap&#xF3;s rodar a <em>migration</em>, voc&#xEA; pode verificar as colunas com os seguintes comandos no console do Rails:</p>
<pre><code class="language-bash">rails db:migrate
rails console
personal_document = PersonalDocument.create(full_name: &quot;Jane Doe&quot;)
puts personal_document.full_name_length  # Deve exibir: 8
</code></pre>
<p>Essa configura&#xE7;&#xE3;o garante que, sempre que o <code>full_name</code> for atualizado, a coluna virtual <code>full_name_length</code> seja recalculada automaticamente e armazenada.</p>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>As colunas virtuais no Rails 7 oferecem uma maneira eficiente de manter dados derivados consistentes, eliminando a necessidade de c&#xE1;lculos redundantes e melhorando o desempenho em consultas. Utilizar colunas virtuais com a op&#xE7;&#xE3;o <code>stored: true</code> pode otimizar a sua aplica&#xE7;&#xE3;o, especialmente em cen&#xE1;rios onde os dados derivados s&#xE3;o frequentemente acessados e precisam ser mantidos em sincronia com outras colunas.</p>]]></content:encoded></item><item><title><![CDATA[Índices Personalizados no Banco de Dados em Rails]]></title><description><![CDATA[<p>Implementar um &#xED;ndice personalizado no banco de dados atrav&#xE9;s de uma <em>migration</em> no Rails &#xE9; uma maneira poderosa de otimizar consultas e melhorar o desempenho da aplica&#xE7;&#xE3;o. &#xCD;ndices podem acelerar significativamente as opera&#xE7;&#xF5;es de recupera&#xE7;&#xE3;o de dados,</p>]]></description><link>https://jcmaciel.com/indices-personalizados-no-banco-de-dados-em-rails/</link><guid isPermaLink="false">66feeff0e60ca600013dfff0</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:27:38 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1648459776041-cbeab708f17b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI5fHxkYXRhYmFzZXxlbnwwfHx8fDE3Mjc5ODM2MDR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1648459776041-cbeab708f17b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI5fHxkYXRhYmFzZXxlbnwwfHx8fDE3Mjc5ODM2MDR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="&#xCD;ndices Personalizados no Banco de Dados em Rails"><p>Implementar um &#xED;ndice personalizado no banco de dados atrav&#xE9;s de uma <em>migration</em> no Rails &#xE9; uma maneira poderosa de otimizar consultas e melhorar o desempenho da aplica&#xE7;&#xE3;o. &#xCD;ndices podem acelerar significativamente as opera&#xE7;&#xF5;es de recupera&#xE7;&#xE3;o de dados, permitindo que o banco de dados encontre linhas de maneira mais eficiente.</p>
<p>Aqui est&#xE1; um guia passo a passo de como implementar um &#xED;ndice personalizado em uma <em>migration</em> no Rails, juntamente com alguns exemplos e boas pr&#xE1;ticas.</p>
<h3 id="passo-1-gerar-uma-migration">Passo 1: Gerar uma Migration</h3>
<p>Primeiro, gere um novo arquivo de <em>migration</em> usando o gerador do Rails. Voc&#xEA; pode fazer isso rodando o seguinte comando:</p>
<pre><code class="language-bash">rails generate migration AddCustomIndexToTableName
</code></pre>
<p>Isso criar&#xE1; um arquivo de <em>migration</em> no diret&#xF3;rio <code>db/migrate</code>.</p>
<h3 id="passo-2-adicionar-o-%C3%ADndice-na-migration">Passo 2: Adicionar o &#xCD;ndice na Migration</h3>
<p>Abra o arquivo de <em>migration</em> gerado e use o m&#xE9;todo <code>add_index</code> para adicionar um &#xED;ndice personalizado &#xE0; sua tabela. Aqui est&#xE3;o alguns exemplos de diferentes tipos de &#xED;ndices que voc&#xEA; pode criar:</p>
<h4 id="%C3%ADndice-b%C3%A1sico">&#xCD;ndice B&#xE1;sico</h4>
<p>Para adicionar um &#xED;ndice simples em uma &#xFA;nica coluna:</p>
<pre><code class="language-ruby">class AddCustomIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, :column_name
  end
end
</code></pre>
<h4 id="%C3%ADndice-composto">&#xCD;ndice Composto</h4>
<p>Para adicionar um &#xED;ndice em m&#xFA;ltiplas colunas (um &#xED;ndice composto), voc&#xEA; pode fazer o seguinte:</p>
<pre><code class="language-ruby">class AddCompositeIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, [:column1, :column2]
  end
end
</code></pre>
<p>Esse tipo de &#xED;ndice &#xE9; &#xFA;til quando voc&#xEA; faz consultas com base em uma combina&#xE7;&#xE3;o de colunas.</p>
<h4 id="%C3%ADndice-%C3%BAnico">&#xCD;ndice &#xDA;nico</h4>
<p>Para garantir que os valores em uma coluna ou em uma combina&#xE7;&#xE3;o de colunas sejam &#xFA;nicos, voc&#xEA; pode adicionar um &#xED;ndice &#xFA;nico:</p>
<pre><code class="language-ruby">class AddUniqueIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, :column_name, unique: true
  end
end
</code></pre>
<h4 id="%C3%ADndice-com-op%C3%A7%C3%B5es">&#xCD;ndice com Op&#xE7;&#xF5;es</h4>
<p>Voc&#xEA; pode personalizar os &#xED;ndices com op&#xE7;&#xF5;es adicionais, como nome, ordem, comprimento, etc.</p>
<h5 id="nome-personalizado-para-o-%C3%ADndice">Nome Personalizado para o &#xCD;ndice</h5>
<pre><code class="language-ruby">class AddCustomNamedIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, :column_name, name: &apos;custom_index_name&apos;
  end
end
</code></pre>
<h5 id="%C3%ADndice-com-ordem-espec%C3%ADfica">&#xCD;ndice com Ordem Espec&#xED;fica</h5>
<p>Alguns bancos de dados suportam &#xED;ndices ordenados, onde voc&#xEA; pode especificar a ordem de classifica&#xE7;&#xE3;o do &#xED;ndice:</p>
<pre><code class="language-ruby">class AddOrderedIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, :column_name, order: { column_name: :desc }
  end
end
</code></pre>
<h5 id="%C3%ADndice-com-limita%C3%A7%C3%A3o-de-comprimento">&#xCD;ndice com Limita&#xE7;&#xE3;o de Comprimento</h5>
<p>Essa op&#xE7;&#xE3;o &#xE9; &#xFA;til para indexar colunas de texto ou string em bancos de dados como o MySQL, que limitam os tamanhos de &#xED;ndices:</p>
<pre><code class="language-ruby">class AddLengthLimitedIndexToTableName &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :table_name, :column_name, length: 10
  end
end
</code></pre>
<h3 id="passo-3-rodar-a-migration">Passo 3: Rodar a Migration</h3>
<p>Depois de definir o &#xED;ndice no arquivo de <em>migration</em>, execute a <em>migration</em> para aplicar as mudan&#xE7;as no seu banco de dados:</p>
<pre><code class="language-bash">rails db:migrate
</code></pre>
<h3 id="passo-4-verificar-o-%C3%ADndice">Passo 4: Verificar o &#xCD;ndice</h3>
<p>Voc&#xEA; pode verificar se o &#xED;ndice foi criado conferindo o schema do banco de dados ou usando comandos espec&#xED;ficos do banco de dados.</p>
<p>Por exemplo, no PostgreSQL, voc&#xEA; pode usar:</p>
<pre><code class="language-sql">\d+ table_name
</code></pre>
<p>No MySQL, voc&#xEA; pode usar:</p>
<pre><code class="language-sql">SHOW INDEX FROM table_name;
</code></pre>
<h3 id="exemplo-adicionando-um-%C3%ADndice-para-otimizar-uma-consulta">Exemplo: Adicionando um &#xCD;ndice para Otimizar uma Consulta</h3>
<p>Considere uma aplica&#xE7;&#xE3;o Rails com uma tabela <code>users</code> onde voc&#xEA; frequentemente faz consultas pelo campo <code>email</code>. Adicionar um &#xED;ndice na coluna <code>email</code> pode melhorar significativamente o desempenho:</p>
<pre><code class="language-ruby">class AddIndexToUsersEmail &lt; ActiveRecord::Migration[6.0]
  def change
    add_index :users, :email, unique: true
  end
end
</code></pre>
<h3 id="boas-pr%C3%A1ticas-para-o-uso-de-%C3%ADndices">Boas Pr&#xE1;ticas para o Uso de &#xCD;ndices</h3>
<ul><li><strong>Analise os Padr&#xF5;es de Consulta:</strong> Adicione &#xED;ndices apenas &#xE0;s colunas que s&#xE3;o frequentemente usadas em condi&#xE7;&#xF5;es de consulta ou como chaves de jun&#xE7;&#xE3;o (<em>joins</em>).</li><li><strong>Evite o Excesso de &#xCD;ndices:</strong> Embora os &#xED;ndices melhorem o desempenho de leitura, eles podem degradar o desempenho de escrita (inser&#xE7;&#xF5;es, atualiza&#xE7;&#xF5;es, exclus&#xF5;es) devido &#xE0; sobrecarga adicional de manuten&#xE7;&#xE3;o do &#xED;ndice. Use-os com modera&#xE7;&#xE3;o.</li><li><strong>Considere &#xCD;ndices Compostos:</strong> Se voc&#xEA; frequentemente faz consultas por m&#xFA;ltiplas colunas, um &#xED;ndice composto pode ser mais eficiente do que v&#xE1;rios &#xED;ndices de coluna &#xFA;nica.</li><li><strong>Use &#xCD;ndices &#xDA;nicos para Restri&#xE7;&#xF5;es de Unicidade:</strong> Se uma coluna ou combina&#xE7;&#xE3;o de colunas deve ser &#xFA;nica, imponha isso com um &#xED;ndice &#xFA;nico.</li><li><strong>Monitore o Uso dos &#xCD;ndices:</strong> Use ferramentas de monitoramento do banco de dados para identificar &#xED;ndices n&#xE3;o utilizados ou de baixo desempenho.</li><li><strong>Fique Atento ao Tamanho do &#xCD;ndice:</strong> &#xCD;ndices grandes podem consumir muito espa&#xE7;o em disco. Considere limita&#xE7;&#xF5;es de comprimento para grandes campos de texto.</li><li><strong>Reconstrua &#xCD;ndices Quando Necess&#xE1;rio:</strong> Ocasionalmente, pode ser necess&#xE1;rio reconstruir &#xED;ndices para otimizar o desempenho, especialmente ap&#xF3;s grandes modifica&#xE7;&#xF5;es de dados.</li></ul>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>Os &#xED;ndices personalizados no Rails s&#xE3;o uma ferramenta essencial para otimizar consultas e melhorar o desempenho da aplica&#xE7;&#xE3;o. Seguindo boas pr&#xE1;ticas e entendendo os padr&#xF5;es de consulta da sua aplica&#xE7;&#xE3;o, voc&#xEA; pode garantir que seus &#xED;ndices sejam eficientes e bem gerenciados, evitando o excesso de &#xED;ndices que podem prejudicar o desempenho de grava&#xE7;&#xE3;o.</p>]]></content:encoded></item><item><title><![CDATA[Ruby 3.0: Otimizando Aplicações com GC.compact]]></title><description><![CDATA[<p>O Ruby 3.0 introduziu um novo m&#xE9;todo no seu coletor de lixo chamado <code>GC.compact</code>, que oferece uma maneira poderosa de gerenciar mem&#xF3;ria ao reduzir a fragmenta&#xE7;&#xE3;o em aplica&#xE7;&#xF5;es de longa dura&#xE7;&#xE3;o. Esse recurso pode gerar</p>]]></description><link>https://jcmaciel.com/ruby-3-0-otimizando-aplicacoes-com-gc-compact/</link><guid isPermaLink="false">66feef6ce60ca600013dffe2</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:25:24 GMT</pubDate><media:content url="https://images.unsplash.com/1/work-stations-plus-espresso.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxjb21wdXRlcnxlbnwwfHx8fDE3Mjc5ODM1MDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/1/work-stations-plus-espresso.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxjb21wdXRlcnxlbnwwfHx8fDE3Mjc5ODM1MDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Ruby 3.0: Otimizando Aplica&#xE7;&#xF5;es com GC.compact"><p>O Ruby 3.0 introduziu um novo m&#xE9;todo no seu coletor de lixo chamado <code>GC.compact</code>, que oferece uma maneira poderosa de gerenciar mem&#xF3;ria ao reduzir a fragmenta&#xE7;&#xE3;o em aplica&#xE7;&#xF5;es de longa dura&#xE7;&#xE3;o. Esse recurso pode gerar melhorias significativas no uso da mem&#xF3;ria e no desempenho geral da aplica&#xE7;&#xE3;o, especialmente em cen&#xE1;rios onde a fragmenta&#xE7;&#xE3;o da mem&#xF3;ria se torna um gargalo.</p>
<h3 id="entendendo-o-gccompact">Entendendo o <code>GC.compact</code></h3>
<p>A coleta de lixo (<em>Garbage Collection</em>, ou GC) &#xE9; um processo cr&#xED;tico no Ruby, respons&#xE1;vel por liberar mem&#xF3;ria ao limpar objetos que n&#xE3;o est&#xE3;o mais em uso. No entanto, com o tempo, especialmente em aplica&#xE7;&#xF5;es que rodam continuamente, pode ocorrer fragmenta&#xE7;&#xE3;o de mem&#xF3;ria. Isso acontece quando a mem&#xF3;ria &#xE9; alocada e desalocada de tal forma que pequenos espa&#xE7;os de mem&#xF3;ria n&#xE3;o utilizados ficam para tr&#xE1;s. Esses espa&#xE7;os vazios podem levar a um uso ineficiente da mem&#xF3;ria e degradar o desempenho, pois o GC tem que trabalhar mais para gerenciar a mem&#xF3;ria fragmentada.</p>
<p>O m&#xE9;todo <code>GC.compact</code> aborda esse problema compactando o <em>heap</em> (onde o Ruby armazena seus objetos). Quando voc&#xEA; chama <code>GC.compact</code>, o coletor de lixo do Ruby reorganiza os objetos na mem&#xF3;ria, movendo-os para mais perto uns dos outros e reduzindo os espa&#xE7;os vazios. Esse layout de mem&#xF3;ria compactado pode ajudar a reduzir o uso de mem&#xF3;ria e melhorar a efici&#xEA;ncia do processo de coleta de lixo.</p>
<h3 id="como-o-gccompact-funciona">Como o <code>GC.compact</code> Funciona</h3>
<p>Quando o <code>GC.compact</code> &#xE9; invocado, ele:</p>
<ul><li><strong>Reorganiza Objetos:</strong> Move os objetos na mem&#xF3;ria para reduzir os espa&#xE7;os vazios e criar blocos cont&#xED;guos de mem&#xF3;ria.</li><li><strong>Otimiza o Layout de Mem&#xF3;ria:</strong> Ao agrupar os objetos, ele reduz a fragmenta&#xE7;&#xE3;o e potencialmente melhora a localidade de cache, levando a tempos de acesso mais r&#xE1;pidos para objetos frequentemente usados.</li><li><strong>Reduz Sobrecarga do GC:</strong> Com um layout de mem&#xF3;ria mais compacto, o GC pode operar de forma mais eficiente, gastando menos tempo procurando por espa&#xE7;os fragmentados na mem&#xF3;ria.</li></ul>
<h3 id="estudo-de-caso-usando-gccompact-em-uma-aplica%C3%A7%C3%A3o-web">Estudo de Caso: Usando <code>GC.compact</code> em uma Aplica&#xE7;&#xE3;o Web</h3>
<p>Vamos considerar um exemplo real de uso do <code>GC.compact</code> em uma aplica&#xE7;&#xE3;o web Ruby on Rails que lida com um alto volume de tr&#xE1;fego. Esta aplica&#xE7;&#xE3;o &#xE9; uma parte cr&#xED;tica de uma grande plataforma de e-commerce, onde uptime e desempenho s&#xE3;o essenciais.</p>
<p><strong>Problema:</strong> Com o tempo, o uso de mem&#xF3;ria da aplica&#xE7;&#xE3;o estava aumentando gradualmente, e, apesar das coletas regulares de lixo, a fragmenta&#xE7;&#xE3;o de mem&#xF3;ria estava causando degrada&#xE7;&#xE3;o no desempenho da aplica&#xE7;&#xE3;o. A equipe notou que, ap&#xF3;s v&#xE1;rios dias de opera&#xE7;&#xE3;o cont&#xED;nua, o consumo de mem&#xF3;ria estava muito acima do esperado, levando a lentid&#xF5;es frequentes e, em alguns casos, a travamentos.</p>
<p><strong>Solu&#xE7;&#xE3;o:</strong> A equipe de desenvolvimento decidiu experimentar o <code>GC.compact</code> para resolver o problema de fragmenta&#xE7;&#xE3;o de mem&#xF3;ria. Eles adicionaram uma tarefa peri&#xF3;dica &#xE0; aplica&#xE7;&#xE3;o, acionando o <code>GC.compact</code> durante hor&#xE1;rios de menor movimento, quando a carga no servidor era mais baixa.</p>
<p><strong>Implementa&#xE7;&#xE3;o:</strong></p>
<pre><code class="language-ruby"># Agenda o GC.compact para rodar durante hor&#xE1;rios de menor movimento
Rails.application.config.after_initialize do
  Thread.new do
    loop do
      sleep 6.hours # Aguarda por 6 horas
      GC.compact # Compacta a mem&#xF3;ria
      Rails.logger.info(&quot;Mem&#xF3;ria compactada pelo GC.compact&quot;)
    end
  end
end
</code></pre>
<p><strong>Resultados:</strong> Ap&#xF3;s implementar o <code>GC.compact</code>, a equipe observou uma redu&#xE7;&#xE3;o significativa no uso de mem&#xF3;ria ao longo do tempo. O footprint de mem&#xF3;ria da aplica&#xE7;&#xE3;o tornou-se mais est&#xE1;vel, e a frequ&#xEA;ncia das pausas do GC diminuiu. O layout de mem&#xF3;ria compactado resultou em menos gargalos de desempenho, levando a tempos de resposta mais r&#xE1;pidos e uma maior confiabilidade.</p>
<p>A principal conclus&#xE3;o deste estudo de caso &#xE9; que o <code>GC.compact</code> pode ser uma ferramenta valiosa para gerenciar mem&#xF3;ria em aplica&#xE7;&#xF5;es Ruby que rodam por per&#xED;odos prolongados. Ao reduzir a fragmenta&#xE7;&#xE3;o, ele ajuda a garantir que a aplica&#xE7;&#xE3;o permane&#xE7;a eficiente e confi&#xE1;vel, mesmo sob carga pesada.</p>
<h3 id="quando-usar-o-gccompact">Quando Usar o <code>GC.compact</code></h3>
<p>Embora o <code>GC.compact</code> possa ser altamente eficaz, &#xE9; importante us&#xE1;-lo com cautela. Compactar a mem&#xF3;ria pode ser uma opera&#xE7;&#xE3;o custosa, ent&#xE3;o &#xE9; geralmente mais adequado para cen&#xE1;rios onde a fragmenta&#xE7;&#xE3;o &#xE9; um problema conhecido. Ele &#xE9; particularmente &#xFA;til em:</p>
<ul><li><strong>Aplica&#xE7;&#xF5;es de longa dura&#xE7;&#xE3;o:</strong> Servidores, jobs em background ou servi&#xE7;os que rodam continuamente e s&#xE3;o propensos &#xE0; fragmenta&#xE7;&#xE3;o de mem&#xF3;ria.</li><li><strong>Aplica&#xE7;&#xF5;es com grande uso de mem&#xF3;ria:</strong> Aplica&#xE7;&#xF5;es com grandes footprints de mem&#xF3;ria, onde a gest&#xE3;o da mem&#xF3;ria &#xE9; crucial para manter o desempenho.</li></ul>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>O <code>GC.compact</code> &#xE9; uma adi&#xE7;&#xE3;o poderosa ao conjunto de ferramentas de coleta de lixo do Ruby, oferecendo uma maneira de reduzir a fragmenta&#xE7;&#xE3;o de mem&#xF3;ria e otimizar o desempenho em aplica&#xE7;&#xF5;es de longa dura&#xE7;&#xE3;o. Ao entender como e quando usar este m&#xE9;todo, voc&#xEA; pode garantir que suas aplica&#xE7;&#xF5;es Ruby permane&#xE7;am eficientes e responsivas, mesmo sob alta carga. Seja lidando com uma aplica&#xE7;&#xE3;o web de alto tr&#xE1;fego ou um servi&#xE7;o de recursos intensivos, o <code>GC.compact</code> pode ser uma parte valiosa de sua estrat&#xE9;gia de otimiza&#xE7;&#xE3;o.</p>
<p>Utilizando essa abordagem, voc&#xEA; estar&#xE1; garantindo que suas aplica&#xE7;&#xF5;es continuem a funcionar de maneira eficiente e sem interrup&#xE7;&#xF5;es, mesmo em cen&#xE1;rios mais exigentes.</p>]]></content:encoded></item><item><title><![CDATA[Dominando Rails Params: com with_defaults]]></title><description><![CDATA[<p>Manipular par&#xE2;metros em Ruby on Rails &#xE9; uma tarefa comum, especialmente ao trabalhar com formul&#xE1;rios e par&#xE2;metros fortes (<em>strong parameters</em>). Um m&#xE9;todo poderoso, mas menos conhecido, que pode simplificar esse processo &#xE9; o <code>with_defaults</code>. Esse m&#xE9;todo permite fornecer valores</p>]]></description><link>https://jcmaciel.com/dominando-rails-params-com-with_defaults/</link><guid isPermaLink="false">66feeebae60ca600013dffd6</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:22:06 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1522776851755-3914469f0ca2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJ1Ynl8ZW58MHx8fHwxNzI3OTgzMzE5fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1522776851755-3914469f0ca2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJ1Ynl8ZW58MHx8fHwxNzI3OTgzMzE5fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Dominando Rails Params: com with_defaults"><p>Manipular par&#xE2;metros em Ruby on Rails &#xE9; uma tarefa comum, especialmente ao trabalhar com formul&#xE1;rios e par&#xE2;metros fortes (<em>strong parameters</em>). Um m&#xE9;todo poderoso, mas menos conhecido, que pode simplificar esse processo &#xE9; o <code>with_defaults</code>. Esse m&#xE9;todo permite fornecer valores padr&#xE3;o para quaisquer chaves ausentes em um <em>hash</em>, tornando o c&#xF3;digo mais limpo e eficiente. Vamos explorar como o <code>with_defaults</code> funciona e como voc&#xEA; pode utiliz&#xE1;-lo de maneira eficaz com par&#xE2;metros fortes.</p>
<h3 id="o-que-%C3%A9-withdefaults">O que &#xE9; <code>with_defaults</code>?</h3>
<p><code>with_defaults</code> &#xE9; um alias para o m&#xE9;todo <code>reverse_merge</code> no Rails. Ele permite mesclar dois <em>hashes</em>, onde os valores do <em>hash</em> fornecido s&#xF3; s&#xE3;o aplicados se n&#xE3;o existirem no <em>hash</em> receptor. &#xC9; particularmente &#xFA;til quando voc&#xEA; deseja garantir que certas chaves tenham valores padr&#xE3;o, sem sobrescrever os valores j&#xE1; existentes.</p>
<h3 id="um-exemplo-pr%C3%A1tico">Um Exemplo Pr&#xE1;tico</h3>
<p>Vamos analisar um exemplo pr&#xE1;tico envolvendo par&#xE2;metros fortes em um <em>controller</em> Rails. Imagine que voc&#xEA; est&#xE1; desenvolvendo uma aplica&#xE7;&#xE3;o de blog e deseja garantir que cada novo post seja associado ao usu&#xE1;rio atual, mas tamb&#xE9;m quer permitir flexibilidade para casos especiais.</p>
<p>Normalmente, voc&#xEA; definiria seu m&#xE9;todo <code>post_params</code> assim:</p>
<pre><code class="language-ruby">def post_params
  params.require(:post).permit(:title)
end
</code></pre>
<p>Mas e se voc&#xEA; quiser garantir que todo novo post seja automaticamente associado ao <code>current_user</code>? Voc&#xEA; pode adicionar um valor padr&#xE3;o para o atributo <code>user</code> usando o <code>with_defaults</code>:</p>
<pre><code class="language-ruby">def post_params
  params.require(:post).permit(:title).with_defaults(user: current_user)
end
</code></pre>
<p>Com esse c&#xF3;digo, se os par&#xE2;metros do post n&#xE3;o inclu&#xED;rem um atributo <code>user</code>, o <code>current_user</code> ser&#xE1; usado como padr&#xE3;o. Essa &#xE9; uma maneira limpa e concisa de garantir que cada post esteja vinculado ao usu&#xE1;rio que o criou, sem precisar definir esse valor manualmente em v&#xE1;rios lugares.</p>
<h3 id="por-que-usar-withdefaults">Por Que Usar <code>with_defaults</code>?</h3>
<ul><li><strong>Simplifica o C&#xF3;digo:</strong> Voc&#xEA; pode evitar verifica&#xE7;&#xF5;es adicionais e l&#xF3;gica condicional ao usar <code>with_defaults</code> para fornecer valores de fallback.</li><li><strong>Previne Erros:</strong> Garantir que valores padr&#xE3;o sejam definidos reduz o risco de dados faltantes ou incompletos.</li><li><strong>Mant&#xE9;m o C&#xF3;digo DRY:</strong> Evita repetir a l&#xF3;gica de definir valores padr&#xE3;o por todo o c&#xF3;digo.</li></ul>
<h3 id="um-exemplo-mais-complexo">Um Exemplo Mais Complexo</h3>
<p>Considere um cen&#xE1;rio em que sua aplica&#xE7;&#xE3;o precisa permitir que certos usu&#xE1;rios administradores especifiquem um autor diferente para um post, enquanto usu&#xE1;rios comuns s&#xF3; devem ser capazes de criar posts para si mesmos. Voc&#xEA; pode ajustar os par&#xE2;metros condicionalmente desta forma:</p>
<pre><code class="language-ruby">def post_params
  permitted_params = params.require(:post).permit(:title)
  
  # Define o usu&#xE1;rio padr&#xE3;o como current_user se n&#xE3;o for fornecido e o usu&#xE1;rio n&#xE3;o for admin
  unless current_user.admin?
    permitted_params = permitted_params.with_defaults(user: current_user)
  end

  permitted_params
end
</code></pre>
<p>Neste exemplo, usu&#xE1;rios comuns s&#xF3; podem criar posts para si mesmos, mas administradores podem definir o par&#xE2;metro <code>user</code> para outra pessoa. Isso mant&#xE9;m a l&#xF3;gica do seu <em>controller</em> limpa e o manuseio dos par&#xE2;metros robusto.</p>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>O <code>with_defaults</code> &#xE9; uma ferramenta poderosa em Rails que permite fornecer valores padr&#xE3;o para par&#xE2;metros de forma eficiente e limpa. Ao utiliz&#xE1;-lo, voc&#xEA; pode simplificar sua l&#xF3;gica, prevenir erros e manter seu c&#xF3;digo DRY, evitando duplica&#xE7;&#xF5;es desnecess&#xE1;rias. Em aplica&#xE7;&#xF5;es onde par&#xE2;metros din&#xE2;micos ou permiss&#xF5;es diferentes s&#xE3;o necess&#xE1;rias, como em nosso exemplo com administradores e usu&#xE1;rios comuns, <code>with_defaults</code> oferece uma solu&#xE7;&#xE3;o pr&#xE1;tica e elegante.</p>
<p>Ao dominar esse m&#xE9;todo, voc&#xEA; estar&#xE1; adicionando mais uma ferramenta valiosa ao seu arsenal de desenvolvimento Rails, ajudando a criar aplica&#xE7;&#xF5;es mais robustas e f&#xE1;ceis de manter.</p>]]></content:encoded></item><item><title><![CDATA[Aplicando a Lei de Demeter na Programação Orientada a Objetos com Rails]]></title><description><![CDATA[<p>Na programa&#xE7;&#xE3;o orientada a objetos (OOP), aderir a princ&#xED;pios que promovem baixo acoplamento e encapsulamento &#xE9; essencial para construir sistemas escal&#xE1;veis e de f&#xE1;cil manuten&#xE7;&#xE3;o. Um desses princ&#xED;pios &#xE9; a Lei de Demeter, tamb&#xE9;m</p>]]></description><link>https://jcmaciel.com/aplicando-a-lei-de-demeter-na-programacao-orientada-a-objetos-com-rails/</link><guid isPermaLink="false">66feee23e60ca600013dffc6</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:20:13 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1607798748738-b15c40d33d57?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNvZGluZ3xlbnwwfHx8fDE3Mjc5ODMxNjd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1607798748738-b15c40d33d57?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNvZGluZ3xlbnwwfHx8fDE3Mjc5ODMxNjd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Aplicando a Lei de Demeter na Programa&#xE7;&#xE3;o Orientada a Objetos com Rails"><p>Na programa&#xE7;&#xE3;o orientada a objetos (OOP), aderir a princ&#xED;pios que promovem baixo acoplamento e encapsulamento &#xE9; essencial para construir sistemas escal&#xE1;veis e de f&#xE1;cil manuten&#xE7;&#xE3;o. Um desses princ&#xED;pios &#xE9; a Lei de Demeter, tamb&#xE9;m conhecida como o Princ&#xED;pio do Menor Conhecimento. Esse princ&#xED;pio ajuda a evitar que objetos saibam demais sobre o funcionamento interno de outros objetos, um problema comum na OOP.</p>
<p>Neste post, vamos explorar a Lei de Demeter e demonstrar como aplic&#xE1;-la em uma aplica&#xE7;&#xE3;o Ruby on Rails. Ao final, voc&#xEA; entender&#xE1; como esse princ&#xED;pio pode simplificar seu c&#xF3;digo e tornar sua aplica&#xE7;&#xE3;o mais f&#xE1;cil de manter.</p>
<h3 id="o-que-%C3%A9-a-lei-de-demeter-na-programa%C3%A7%C3%A3o-orientada-a-objetos">O que &#xE9; a Lei de Demeter na Programa&#xE7;&#xE3;o Orientada a Objetos?</h3>
<p>Na programa&#xE7;&#xE3;o orientada a objetos, a Lei de Demeter (LoD) pode ser resumida com a seguinte regra: &quot;Um objeto deve se comunicar apenas com seus amigos imediatos e n&#xE3;o com estranhos.&quot;</p>
<p>Para ser mais claro, um objeto deve invocar m&#xE9;todos apenas em:</p>
<ul><li>Ele mesmo.</li><li>Suas depend&#xEA;ncias diretas (campos ou vari&#xE1;veis de inst&#xE2;ncia).</li><li>Objetos passados como argumentos.</li><li>Objetos que ele cria.</li></ul>
<p>Essa regra reduz as depend&#xEA;ncias entre objetos, tornando o c&#xF3;digo menos fr&#xE1;gil e mais f&#xE1;cil de manter. Quando um objeto &quot;atravessa&quot; outro para acessar o m&#xE9;todo de um terceiro objeto (ex.: <code>pedido.cliente.endereco.cidade</code>), cria-se um acoplamento forte. Esse tipo de c&#xF3;digo &#xE9; mais dif&#xED;cil de testar, estender e depurar.</p>
<h3 id="o-problema-quebrando-a-lei-de-demeter">O Problema: Quebrando a Lei de Demeter</h3>
<p>Vamos analisar um exemplo comum em uma aplica&#xE7;&#xE3;o Rails onde a Lei de Demeter &#xE9; violada. Suponha que temos tr&#xEA;s modelos: <code>Pedido</code>, <code>Cliente</code> e <code>Endereco</code>. Um Pedido pertence a um Cliente, e um Cliente possui um Endere&#xE7;o. No c&#xF3;digo abaixo, o Pedido calcula um pre&#xE7;o de envio com desconto baseado no endere&#xE7;o do cliente.</p>
<pre><code class="language-ruby">class Pedido
  def preco_envio_com_desconto(codigo_desconto)
    cupom = Cupom.new(codigo_desconto)
    cupom.desconto(cliente.endereco.preco_envio)
  end
end
</code></pre>
<p>Essa implementa&#xE7;&#xE3;o viola a Lei de Demeter. O objeto <code>Pedido</code> est&#xE1; acessando <code>Cliente</code> para chegar a <code>Endereco</code> e buscar o <code>preco_envio</code>. Isso leva a uma situa&#xE7;&#xE3;o em que <code>Pedido</code> sabe demais sobre a estrutura interna de <code>Cliente</code> e <code>Endereco</code>, resultando em um forte acoplamento entre esses objetos.</p>
<h3 id="refatora%C3%A7%C3%A3o-aplicando-a-lei-de-demeter">Refatora&#xE7;&#xE3;o: Aplicando a Lei de Demeter</h3>
<p>Para corrigir isso, podemos mover a responsabilidade de calcular o pre&#xE7;o de envio com desconto para o modelo <code>Cliente</code>. Dessa forma, <code>Pedido</code> interage apenas com seu colaborador direto, <code>Cliente</code>, enquanto <code>Cliente</code> gerencia sua rela&#xE7;&#xE3;o com <code>Endereco</code>.</p>
<p>Aqui est&#xE1; o c&#xF3;digo refatorado:</p>
<pre><code class="language-ruby">class Pedido
  def preco_envio_com_desconto(codigo_desconto)
    cliente.preco_envio_com_desconto(codigo_desconto)
  end
end

class Cliente
  def preco_envio_com_desconto(codigo_desconto)
    cupom = Cupom.new(codigo_desconto)
    cupom.desconto(endereco.preco_envio)
  end
end
</code></pre>
<p>Agora, a classe <code>Pedido</code> n&#xE3;o acessa diretamente <code>Endereco</code>. Em vez disso, delega o c&#xE1;lculo ao objeto <code>Cliente</code>, o que reduz o acoplamento e torna o sistema mais f&#xE1;cil de manter.</p>
<h3 id="usando-delegate-para-um-c%C3%B3digo-ainda-mais-limpo">Usando <code>delegate</code> para um C&#xF3;digo Ainda Mais Limpo</h3>
<p>Podemos levar essa refatora&#xE7;&#xE3;o um passo adiante usando o m&#xE9;todo <code>delegate</code> do Rails. O m&#xE9;todo <code>delegate</code> permite encaminhar chamadas de m&#xE9;todos automaticamente de um objeto para outro, tornando o c&#xF3;digo mais limpo e f&#xE1;cil de ler.</p>
<p>Veja como podemos refatorar o exemplo anterior usando <code>delegate</code>:</p>
<pre><code class="language-ruby">class Pedido
  belongs_to :cliente

  # Delegar preco_envio_com_desconto ao cliente
  delegate :preco_envio_com_desconto, to: :cliente
end

class Cliente
  has_one :endereco

  def preco_envio_com_desconto(codigo_desconto)
    cupom = Cupom.new(codigo_desconto)
    cupom.desconto(endereco.preco_envio)
  end
end
</code></pre>
<h3 id="como-isso-funciona">Como Isso Funciona?</h3>
<ul><li><strong>Em <code>Pedido</code>:</strong> A linha <code>delegate :preco_envio_com_desconto, to: :cliente</code> permite que <code>Pedido</code> delegue a chamada para <code>Cliente</code> sem precisar definir o m&#xE9;todo manualmente.</li><li><strong>Em <code>Cliente</code>:</strong> O m&#xE9;todo <code>preco_envio_com_desconto</code> gerencia a intera&#xE7;&#xE3;o com <code>Endereco</code> e aplica a l&#xF3;gica de desconto.</li></ul>
<p>Essa refatora&#xE7;&#xE3;o torna o c&#xF3;digo mais limpo, ao mesmo tempo em que respeita a Lei de Demeter.</p>
<h3 id="por-que-seguir-a-lei-de-demeter">Por Que Seguir a Lei de Demeter?</h3>
<ol><li><strong>Baixo Acoplamento</strong><br>Seguindo a Lei de Demeter, os objetos n&#xE3;o precisam conhecer os detalhes internos de outros objetos. Isso reduz a probabilidade de que uma mudan&#xE7;a em uma parte do sistema quebre outra parte. Por exemplo, se alterarmos a estrutura de <code>Endereco</code>, <code>Pedido</code> n&#xE3;o precisar&#xE1; ser modificado.</li><li><strong>Encapsulamento</strong><br>Cada classe &#xE9; respons&#xE1;vel por sua pr&#xF3;pria l&#xF3;gica. No nosso exemplo, a classe <code>Cliente</code> &#xE9; respons&#xE1;vel por gerenciar o endere&#xE7;o e o pre&#xE7;o de envio, enquanto <code>Pedido</code> foca nos detalhes do pedido. Essa clara separa&#xE7;&#xE3;o de responsabilidades torna o c&#xF3;digo mais f&#xE1;cil de entender e manter.</li><li><strong>Melhor Manutenibilidade</strong><br>Menos conhecimento sobre as estruturas de outros objetos significa menos depend&#xEA;ncias. Isso torna o c&#xF3;digo mais flex&#xED;vel e mais f&#xE1;cil de refatorar no futuro. Se a l&#xF3;gica de neg&#xF3;cios em torno do envio mudar, voc&#xEA; s&#xF3; precisar&#xE1; atualizar o modelo <code>Cliente</code>, sem impactar <code>Pedido</code>.</li></ol>
<h3 id="conclus%C3%A3o">Conclus&#xE3;o</h3>
<p>A Lei de Demeter &#xE9; um princ&#xED;pio chave na programa&#xE7;&#xE3;o orientada a objetos que ajuda a reduzir o acoplamento e a promover uma melhor organiza&#xE7;&#xE3;o do c&#xF3;digo. Em aplica&#xE7;&#xF5;es Rails, aderir a esse princ&#xED;pio resulta em sistemas mais escal&#xE1;veis e f&#xE1;ceis de manter. Refatorar seu c&#xF3;digo para delegar responsabilidades e limitar o conhecimento de um objeto sobre os outros cria uma arquitetura de aplica&#xE7;&#xE3;o mais limpa e robusta.</p>
<p>No nosso exemplo com <code>Pedido</code>, <code>Cliente</code> e <code>Endereco</code>, vimos como &#xE9; f&#xE1;cil quebrar a Lei de Demeter e como o uso do m&#xE9;todo <code>delegate</code> do Rails pode ajudar a corrigir isso. &#xC0; medida que sua aplica&#xE7;&#xE3;o Rails cresce, aplicar a Lei de Demeter garantir&#xE1; que sua base de c&#xF3;digo permane&#xE7;a limpa, f&#xE1;cil de manter e extens&#xED;vel.</p>
<h3 id="principais-conclus%C3%B5es">Principais Conclus&#xF5;es:</h3>
<ul><li>A Lei de Demeter incentiva que objetos se comuniquem apenas com seus colaboradores imediatos, reduzindo as depend&#xEA;ncias.</li><li>Violar essa lei resulta em c&#xF3;digo fortemente acoplado, que &#xE9; mais dif&#xED;cil de manter.</li><li>Usar o m&#xE9;todo <code>delegate</code> do Rails facilita a aplica&#xE7;&#xE3;o desse princ&#xED;pio, resultando em um c&#xF3;digo mais limpo e modular.</li></ul>]]></content:encoded></item><item><title><![CDATA[Entendendo Struct em Ruby on Rails]]></title><description><![CDATA[<p>O Ruby &#xE9; conhecido por sua sintaxe elegante e flexibilidade, permitindo que os desenvolvedores criem c&#xF3;digos concisos e leg&#xED;veis. Um dos recursos menos conhecidos, mas poderosos no Ruby, &#xE9; o <code>Struct</code>, uma classe embutida que oferece uma maneira simples de agrupar atributos relacionados sem a sobrecarga</p>]]></description><link>https://jcmaciel.com/entendendo-struct-em-ruby-on-rails/</link><guid isPermaLink="false">66feed48e60ca600013dffba</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:16:43 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1483817101829-339b08e8d83f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHByb2dyYW1taW5nfGVufDB8fHx8MTcyNzk4Mjk5Mnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1483817101829-339b08e8d83f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHByb2dyYW1taW5nfGVufDB8fHx8MTcyNzk4Mjk5Mnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Entendendo Struct em Ruby on Rails"><p>O Ruby &#xE9; conhecido por sua sintaxe elegante e flexibilidade, permitindo que os desenvolvedores criem c&#xF3;digos concisos e leg&#xED;veis. Um dos recursos menos conhecidos, mas poderosos no Ruby, &#xE9; o <code>Struct</code>, uma classe embutida que oferece uma maneira simples de agrupar atributos relacionados sem a sobrecarga de definir uma classe completa. Embora n&#xE3;o seja t&#xE3;o comumente utilizado quanto os modelos ActiveRecord ou POROs (Plain Old Ruby Objects), o <code>Struct</code> pode ser extremamente &#xFA;til em aplica&#xE7;&#xF5;es Rails em certos cen&#xE1;rios.</p>
<h3 id="o-que-%C3%A9-struct">O que &#xE9; Struct?</h3>
<p><code>Struct</code> em Ruby &#xE9; um atalho para definir classes simples que agrupam alguns atributos, fornecendo m&#xE9;todos getters e setters para esses atributos automaticamente. Ele cria uma nova classe que se comporta como um objeto leve, com os atributos que voc&#xEA; define ao inicializar.</p>
<p>Por exemplo, digamos que voc&#xEA; queira criar um objeto simples para representar um ponto em um espa&#xE7;o 2D com coordenadas <code>x</code> e <code>y</code>. Voc&#xEA; pode fazer isso da seguinte forma:</p>
<pre><code class="language-ruby">Point = Struct.new(:x, :y)

point = Point.new(10, 20)
puts point.x  # Sa&#xED;da: 10
puts point.y  # Sa&#xED;da: 20
</code></pre>
<p>Aqui, <code>Struct.new</code> gera uma classe <code>Point</code> com os atributos <code>x</code> e <code>y</code>, al&#xE9;m de m&#xE9;todos para obter e definir esses valores. Nesse caso, o <code>Struct</code> economiza o trabalho de definir explicitamente uma classe com um inicializador e acessores para esses atributos.</p>
<h3 id="quando-usar-struct-no-rails">Quando Usar Struct no Rails</h3>
<p>Embora voc&#xEA; trabalhe principalmente com modelos ActiveRecord e objetos de servi&#xE7;o no Rails, o <code>Struct</code> tem seu lugar para objetos simples e leves que n&#xE3;o precisam das capacidades completas de um modelo. Aqui est&#xE3;o alguns casos onde o <code>Struct</code> pode ser &#xFA;til:</p>
<h4 id="1-armazenamento-tempor%C3%A1rio-de-dados">1. Armazenamento Tempor&#xE1;rio de Dados</h4>
<p>Quando voc&#xEA; precisa armazenar dados temporariamente, mas n&#xE3;o deseja criar um modelo ou classe completa, o <code>Struct</code> &#xE9; ideal. Isso &#xE9; especialmente verdadeiro quando os dados n&#xE3;o precisam persistir no banco de dados, existindo apenas durante uma requisi&#xE7;&#xE3;o ou sess&#xE3;o.</p>
<p><strong>Exemplo:</strong> Imagine que voc&#xEA; est&#xE1; trabalhando em um sistema de reservas e deseja criar um objeto de resumo de viagem sem salv&#xE1;-lo no banco de dados.</p>
<pre><code class="language-ruby">TripSummary = Struct.new(:destination, :duration, :price)

summary = TripSummary.new(&quot;Hava&#xED;&quot;, &quot;7 dias&quot;, 1500)
puts summary.destination  # Sa&#xED;da: Hava&#xED;
puts summary.price        # Sa&#xED;da: 1500
</code></pre>
<h4 id="2-respostas-de-api">2. Respostas de API</h4>
<p>Se a sua aplica&#xE7;&#xE3;o Rails interage com APIs externas, voc&#xEA; pode receber respostas JSON que se mapeiam para dados estruturados. Voc&#xEA; pode facilmente envolver essas respostas em um <code>Struct</code> para tornar o manuseio delas mais organizado e leg&#xED;vel.</p>
<p><strong>Exemplo:</strong> Suponha que voc&#xEA; esteja trabalhando com uma API que retorna dados clim&#xE1;ticos:</p>
<pre><code class="language-ruby">WeatherData = Struct.new(:temperature, :humidity, :wind_speed)

response = { temperature: 75, humidity: 65, wind_speed: 10 }
weather = WeatherData.new(response[:temperature], response[:humidity], response[:wind_speed])

puts weather.temperature  # Sa&#xED;da: 75
puts weather.humidity     # Sa&#xED;da: 65
</code></pre>
<p>Usar <code>Struct</code> aqui ajuda a encapsular a resposta em um objeto claro e espec&#xED;fico para o dom&#xED;nio.</p>
<h4 id="3-objetos-de-formul%C3%A1rio">3. Objetos de Formul&#xE1;rio</h4>
<p>No Rails, objetos de formul&#xE1;rio s&#xE3;o frequentemente usados para lidar com formul&#xE1;rios complexos que envolvem m&#xFA;ltiplos modelos ou atributos que n&#xE3;o s&#xE3;o do banco de dados. Em vez de criar uma classe nova para cada formul&#xE1;rio, voc&#xEA; pode usar <code>Struct</code> para reunir atributos temporariamente.</p>
<p><strong>Exemplo:</strong> Suponha que voc&#xEA; esteja construindo um processo de inscri&#xE7;&#xE3;o com v&#xE1;rias etapas. Em uma etapa, voc&#xEA; precisa coletar informa&#xE7;&#xF5;es pessoais:</p>
<pre><code class="language-ruby">PersonalInfo = Struct.new(:first_name, :last_name, :email)

info = PersonalInfo.new(&quot;John&quot;, &quot;Doe&quot;, &quot;john.doe@example.com&quot;)
</code></pre>
<p>Com isso, voc&#xEA; pode passar o objeto <code>PersonalInfo</code>, tornando o processo do formul&#xE1;rio mais gerenci&#xE1;vel.</p>
<h3 id="melhorando-o-struct-com-m%C3%A9todos-personalizados">Melhorando o Struct com M&#xE9;todos Personalizados</h3>
<p>Uma das grandes vantagens do <code>Struct</code> &#xE9; que ele se comporta como uma classe Ruby regular, ent&#xE3;o voc&#xEA; pode adicionar m&#xE9;todos personalizados a ele. Isso permite encapsular l&#xF3;gica relacionada ao seu objeto <code>Struct</code>.</p>
<p><strong>Exemplo:</strong> Vamos melhorar o exemplo do <code>TripSummary</code> adicionando um m&#xE9;todo para calcular o custo total com impostos.</p>
<pre><code class="language-ruby">TripSummary = Struct.new(:destination, :duration, :price) do
  def total_cost_with_tax(tax_rate)
    price + (price * tax_rate)
  end
end

summary = TripSummary.new(&quot;Hava&#xED;&quot;, &quot;7 dias&quot;, 1500)
puts summary.total_cost_with_tax(0.10)  # Sa&#xED;da: 1650
</code></pre>
<p>Isso permite manter a l&#xF3;gica relacionada dentro do objeto, assim como faria com uma classe completa.</p>
<h3 id="comparando-struct-com-poros-e-modelos">Comparando Struct com POROs e Modelos</h3>
<p>Embora o <code>Struct</code> seja uma ferramenta &#xFA;til, &#xE9; importante saber quando n&#xE3;o us&#xE1;-lo. Aqui est&#xE1; uma compara&#xE7;&#xE3;o r&#xE1;pida entre <code>Struct</code> e outros objetos comuns no Rails:</p>
<table>
<thead>
<tr>
<th>Aspecto</th>
<th>Struct</th>
<th>PORO</th>
<th>Modelo ActiveRecord</th>
</tr>
</thead>
<tbody>
<tr>
<td>Complexidade</td>
<td>Leve, simples</td>
<td>Pode ser leve ou complexo</td>
<td>ORM completo</td>
</tr>
<tr>
<td>Persist&#xEA;ncia</td>
<td>Sem intera&#xE7;&#xE3;o com banco</td>
<td>Sem intera&#xE7;&#xE3;o com banco</td>
<td>Interage com banco</td>
</tr>
<tr>
<td>Personaliza&#xE7;&#xE3;o</td>
<td>F&#xE1;cil de definir m&#xE9;todos</td>
<td>Totalmente personaliz&#xE1;vel</td>
<td>Totalmente personaliz&#xE1;vel</td>
</tr>
<tr>
<td>Caso de Uso</td>
<td>Dados tempor&#xE1;rios, API, formul&#xE1;rios</td>
<td>L&#xF3;gica de neg&#xF3;cios, objetos de servi&#xE7;o</td>
<td>Dados persistentes, l&#xF3;gica de neg&#xF3;cios</td>
</tr>
</tbody>
</table>
<p>O <code>Struct</code> em Ruby on Rails &#xE9; uma maneira vers&#xE1;til e eficiente de lidar com estruturas de dados simples sem a necessidade de classes completas ou modelos ActiveRecord. &#xC9; perfeito para tarefas leves, como armazenamento tempor&#xE1;rio de dados, manipula&#xE7;&#xE3;o de respostas de API ou encapsulamento de atributos de formul&#xE1;rio. Usando <code>Struct</code> no contexto certo, voc&#xEA; pode simplificar seu c&#xF3;digo e torn&#xE1;-lo mais leg&#xED;vel, evitando complexidade desnecess&#xE1;ria.</p>]]></content:encoded></item><item><title><![CDATA[4 Dicas para Resolver Problemas de N+1 Queries em Ruby on Rails]]></title><description><![CDATA[<h2 id="ruby-on-rails"><br>Ruby on Rails</h2>
<p>Os problemas de N+1 queries em Ruby on Rails ocorrem quando sua aplica&#xE7;&#xE3;o faz um n&#xFA;mero excessivo de consultas ao banco de dados devido ao carregamento das associa&#xE7;&#xF5;es entre modelos. Isso pode causar uma degrada&#xE7;&#xE3;o</p>]]></description><link>https://jcmaciel.com/4-dicas-para-resolver-problemas-de-n-1-queries-em-ruby-on-rails/</link><guid isPermaLink="false">66feec8be60ca600013dffae</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Thu, 03 Oct 2024 19:13:37 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1489875347897-49f64b51c1f8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHNxbCUyMHF1ZXJpZXxlbnwwfHx8fDE3Mjc5ODI3OTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h2 id="ruby-on-rails"><br>Ruby on Rails</h2>
<img src="https://images.unsplash.com/photo-1489875347897-49f64b51c1f8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHNxbCUyMHF1ZXJpZXxlbnwwfHx8fDE3Mjc5ODI3OTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="4 Dicas para Resolver Problemas de N+1 Queries em Ruby on Rails"><p>Os problemas de N+1 queries em Ruby on Rails ocorrem quando sua aplica&#xE7;&#xE3;o faz um n&#xFA;mero excessivo de consultas ao banco de dados devido ao carregamento das associa&#xE7;&#xF5;es entre modelos. Isso pode causar uma degrada&#xE7;&#xE3;o significativa no desempenho, especialmente conforme o volume de dados aumenta.</p>
<p>Neste post, vamos abordar quatro maneiras eficazes de resolver o problema de N+1 queries em Rails, tornando sua aplica&#xE7;&#xE3;o mais r&#xE1;pida e eficiente.</p>
<h3 id="1-use-includes-para-eager-loading">1. Use <code>includes</code> para Eager Loading</h3>
<p>A solu&#xE7;&#xE3;o mais comum para problemas de N+1 &#xE9; o uso de <code>includes</code>. Esse m&#xE9;todo permite carregar registros associados em uma &#xFA;nica consulta, em vez de consultar o banco de dados cada vez que uma associa&#xE7;&#xE3;o &#xE9; acessada.</p>
<p><strong>Sem <code>includes</code> (Problema de N+1):</strong></p>
<pre><code class="language-ruby">posts = Post.all
posts.each do |post|
  post.comments.each do |comment|
    puts comment.body
  end
end
</code></pre>
<p>Neste exemplo, para cada post, o Rails executar&#xE1; uma consulta separada para buscar os coment&#xE1;rios associados. Isso pode resultar rapidamente em dezenas ou at&#xE9; centenas de consultas &#xE0; medida que o n&#xFA;mero de posts cresce.</p>
<p><strong>Com <code>includes</code> (Resolvendo N+1):</strong></p>
<pre><code class="language-ruby">posts = Post.includes(:comments).all
posts.each do |post|
  post.comments.each do |comment|
    puts comment.body
  end
end
</code></pre>
<p>Ao usar <code>includes(:comments)</code>, o Rails carregar&#xE1; os posts e seus coment&#xE1;rios associados em uma &#xFA;nica consulta, evitando o problema de N+1.</p>
<h3 id="2-use-joins-para-efici%C3%AAncia-nas-consultas">2. Use <code>joins</code> para Efici&#xEA;ncia nas Consultas</h3>
<p>Se voc&#xEA; n&#xE3;o precisa carregar os registros associados na mem&#xF3;ria e s&#xF3; precisa deles para filtros ou condi&#xE7;&#xF5;es, o uso de <code>joins</code> &#xE9; uma solu&#xE7;&#xE3;o mais eficiente. Enquanto <code>includes</code> carrega os registros associados, <code>joins</code> utiliza SQL para combinar os dados sem buscar todos os registros relacionados.</p>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-ruby">Post.joins(:comments).where(comments: { approved: true })
</code></pre>
<p>Neste caso, <code>joins</code> cria um <code>INNER JOIN</code> em SQL entre as tabelas de posts e coment&#xE1;rios, permitindo que voc&#xEA; filtre os posts com coment&#xE1;rios aprovados sem carregar todos os dados dos coment&#xE1;rios na mem&#xF3;ria.</p>
<h3 id="3-considere-preload-ou-eagerload-em-casos-espec%C3%ADficos">3. Considere <code>preload</code> ou <code>eager_load</code> em Casos Espec&#xED;ficos</h3>
<p>Tanto <code>preload</code> quanto <code>eager_load</code> s&#xE3;o varia&#xE7;&#xF5;es de eager loading no Rails, mas funcionam de maneira um pouco diferente de <code>includes</code>.</p>
<ul><li><strong><code>preload</code>:</strong> Carrega os registros associados em consultas separadas, em vez de usar um join. Isso pode ser &#xFA;til quando voc&#xEA; n&#xE3;o quer lidar com joins, mas ainda precisa evitar o problema de N+1.</li><li><strong><code>eager_load</code>:</strong> For&#xE7;a o Rails a usar um <code>LEFT OUTER JOIN</code> para carregar tanto os registros prim&#xE1;rios quanto os associados em uma &#xFA;nica consulta.</li></ul>
<p><strong>Quando us&#xE1;-los:</strong></p>
<ul><li>Use <code>preload</code> se voc&#xEA; estiver lidando com um grande conjunto de dados e quiser evitar joins complexos.</li><li>Use <code>eager_load</code> quando quiser garantir que todas as associa&#xE7;&#xF5;es sejam carregadas em uma &#xFA;nica consulta.</li></ul>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-ruby">Post.preload(:comments).all # Consultas separadas para posts e coment&#xE1;rios
Post.eager_load(:comments).all # Uma &#xFA;nica consulta com LEFT OUTER JOIN
</code></pre>
<h3 id="4-selecione-apenas-os-dados-necess%C3%A1rios">4. Selecione Apenas os Dados Necess&#xE1;rios</h3>
<p>Outra maneira de otimizar suas consultas &#xE9; selecionar apenas as colunas que voc&#xEA; precisa do banco de dados. Por padr&#xE3;o, o Rails carrega todas as colunas das tabelas associadas, mas muitas vezes voc&#xEA; n&#xE3;o precisa de todas elas.</p>
<p>Voc&#xEA; pode usar <code>select</code> para carregar apenas os dados relevantes:</p>
<pre><code class="language-ruby">posts = Post.select(:id, :title).includes(:comments).all
posts.each do |post|
  puts post.title
end
</code></pre>
<p>Neste caso, em vez de carregar todas as colunas da tabela de posts, estamos selecionando apenas as colunas <code>id</code> e <code>title</code>, reduzindo a quantidade de dados sendo buscados no banco de dados.</p>
<hr>
<p>Com essas quatro dicas, voc&#xEA; pode melhorar significativamente o desempenho da sua aplica&#xE7;&#xE3;o Rails, evitando o problema de N+1 queries e tornando suas consultas ao banco de dados mais eficientes.</p>]]></content:encoded></item><item><title><![CDATA[Hotwire Native: A Nova Era para Desenvolvimento de Aplicativos Móveis Nativos com Abordagem Web-First]]></title><description><![CDATA[<p>No cen&#xE1;rio atual de desenvolvimento de software, especialmente para dispositivos m&#xF3;veis, as demandas por agilidade, efici&#xEA;ncia e simplicidade no processo de cria&#xE7;&#xE3;o de aplicativos s&#xE3;o maiores do que nunca. Tradicionalmente, o desenvolvimento de aplicativos m&#xF3;veis exige que</p>]]></description><link>https://jcmaciel.com/hotwire-native-a-nova-era-para-desenvolvimento-de-aplicativos-moveis-nativos-com-abordagem-web-first/</link><guid isPermaLink="false">66f69a6fe60ca600013dff9e</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Fri, 27 Sep 2024 11:45:06 GMT</pubDate><media:content url="https://jcmaciel.com/content/images/2024/09/native-vs-web.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://jcmaciel.com/content/images/2024/09/native-vs-web.jpg" alt="Hotwire Native: A Nova Era para Desenvolvimento de Aplicativos M&#xF3;veis Nativos com Abordagem Web-First"><p>No cen&#xE1;rio atual de desenvolvimento de software, especialmente para dispositivos m&#xF3;veis, as demandas por agilidade, efici&#xEA;ncia e simplicidade no processo de cria&#xE7;&#xE3;o de aplicativos s&#xE3;o maiores do que nunca. Tradicionalmente, o desenvolvimento de aplicativos m&#xF3;veis exige que equipes construam separadamente para as plataformas iOS e Android, resultando em trabalho duplicado e aumento de custos e tempo. Por&#xE9;m, uma nova solu&#xE7;&#xE3;o tem ganhado destaque no mercado, oferecendo uma abordagem inovadora e poderosa: <strong>Hotwire Native</strong>.</p>
<p>Lan&#xE7;ado como um framework web-first, o <strong>Hotwire Native</strong> promete revolucionar a maneira como desenvolvemos aplicativos m&#xF3;veis nativos, permitindo que desenvolvedores construam aplicativos m&#xF3;veis reutilizando suas interfaces web j&#xE1; existentes, integrando-as perfeitamente com funcionalidades nativas dos dispositivos. Neste artigo, vamos explorar o que &#xE9; o Hotwire Native, como ele funciona, seus benef&#xED;cios e como ele pode ser o futuro do desenvolvimento mobile.</p>
<h2 id="o-que-%C3%A9-o-hotwire-native">O Que &#xE9; o Hotwire Native?</h2>
<p>O <strong>Hotwire Native</strong> &#xE9; uma extens&#xE3;o da fam&#xED;lia Hotwire (HTML Over The Wire), que oferece uma abordagem inovadora para o desenvolvimento de aplicativos m&#xF3;veis nativos. Ao inv&#xE9;s de desenvolver aplicativos separadamente para cada plataforma (Android e iOS), o Hotwire Native permite que desenvolvedores reutilizem suas interfaces web j&#xE1; existentes, utilizando HTML, CSS e outras tecnologias web, para criar experi&#xEA;ncias m&#xF3;veis nativas e fluidas.</p>
<p>O Hotwire Native permite que os desenvolvedores mantenham uma base de c&#xF3;digo web-first e ainda assim aproveitem as transi&#xE7;&#xF5;es e comportamentos nativos dos sistemas operacionais m&#xF3;veis. Isso significa que, ao construir uma aplica&#xE7;&#xE3;o web, voc&#xEA; pode estender seu uso para dispositivos m&#xF3;veis sem a necessidade de construir do zero ou manter bases de c&#xF3;digo completamente distintas.</p>
<h2 id="como-funciona-o-hotwire-native">Como Funciona o Hotwire Native?</h2>
<p>A base do Hotwire Native est&#xE1; no conceito de <strong>Turbo</strong>, que &#xE9; uma das principais bibliotecas da fam&#xED;lia Hotwire. O Turbo &#xE9; respons&#xE1;vel por carregar rapidamente as p&#xE1;ginas HTML e fornecer transi&#xE7;&#xF5;es fluidas entre as diferentes se&#xE7;&#xF5;es do aplicativo, sem a necessidade de recarregar completamente a p&#xE1;gina. O Turbo Native, que faz parte dessa tecnologia, permite que essas transi&#xE7;&#xF5;es ocorram de forma nativa nos aplicativos m&#xF3;veis, criando uma experi&#xEA;ncia r&#xE1;pida e responsiva para os usu&#xE1;rios.</p>
<h3 id="principais-componentes">Principais Componentes:</h3>
<ol><li><strong>Turbo Frames e Turbo Streams</strong>: Esses s&#xE3;o os blocos de constru&#xE7;&#xE3;o que permitem que partes da p&#xE1;gina sejam atualizadas dinamicamente sem a necessidade de recarregar a p&#xE1;gina inteira. Eles oferecem uma maneira de manter uma &#xFA;nica fonte de verdade para os dados, tornando a sincroniza&#xE7;&#xE3;o entre a web e o app nativo mais eficiente.</li><li><strong>Reutiliza&#xE7;&#xE3;o de HTML</strong>: Uma das maiores vantagens do Hotwire Native &#xE9; a possibilidade de reutilizar as mesmas views HTML da web para os apps m&#xF3;veis. Isso significa que se voc&#xEA; j&#xE1; possui uma aplica&#xE7;&#xE3;o web, pode adapt&#xE1;-la para o mobile sem a necessidade de escrever c&#xF3;digo nativo ou duplicar o esfor&#xE7;o de desenvolvimento.</li><li><strong>Integra&#xE7;&#xE3;o com APIs Nativas</strong>: Embora as interfaces sejam baseadas em HTML, o Hotwire Native oferece a capacidade de integrar com as APIs nativas dos dispositivos, como geolocaliza&#xE7;&#xE3;o, c&#xE2;mera, notifica&#xE7;&#xF5;es push, entre outras. Isso permite que o desenvolvedor tenha o melhor dos dois mundos: simplicidade no desenvolvimento com HTML e CSS e acesso a funcionalidades poderosas dos dispositivos m&#xF3;veis.</li></ol>
<h2 id="vantagens-do-hotwire-native">Vantagens do Hotwire Native</h2>
<p>O Hotwire Native vem com uma s&#xE9;rie de vantagens que podem beneficiar desde pequenas startups at&#xE9; grandes empresas que precisam otimizar seus fluxos de trabalho de desenvolvimento. Algumas das principais vantagens incluem:</p>
<h3 id="1-desenvolvimento-acelerado">1. <strong>Desenvolvimento Acelerado</strong></h3>
<p>A maior vantagem do Hotwire Native &#xE9; a capacidade de reutilizar grande parte do c&#xF3;digo j&#xE1; existente de uma aplica&#xE7;&#xE3;o web para construir um app m&#xF3;vel. Isso economiza tempo e esfor&#xE7;o, permitindo que equipes pequenas e &#xE1;geis lancem aplicativos nativos de alta qualidade sem a necessidade de contratar equipes especializadas em iOS e Android.</p>
<h3 id="2-manuten%C3%A7%C3%A3o-simplificada">2. <strong>Manuten&#xE7;&#xE3;o Simplificada</strong></h3>
<p>Manter m&#xFA;ltiplos aplicativos em diferentes plataformas pode ser uma dor de cabe&#xE7;a para equipes de desenvolvimento. Com o Hotwire Native, voc&#xEA; pode manter uma &#xFA;nica base de c&#xF3;digo web que ser&#xE1; utilizada tanto para a vers&#xE3;o desktop quanto para os aplicativos m&#xF3;veis. Isso simplifica a manuten&#xE7;&#xE3;o, reduz erros e diminui o custo de longo prazo, j&#xE1; que atualiza&#xE7;&#xF5;es e corre&#xE7;&#xF5;es s&#xE3;o implementadas uma vez e aplicadas em todas as plataformas.</p>
<h3 id="3-experi%C3%AAncia-nativa">3. <strong>Experi&#xEA;ncia Nativa</strong></h3>
<p>Apesar de reutilizar HTML e CSS, o Hotwire Native garante que os aplicativos m&#xF3;veis ofere&#xE7;am uma experi&#xEA;ncia nativa para os usu&#xE1;rios. Isso &#xE9; poss&#xED;vel gra&#xE7;as ao Turbo Native, que proporciona transi&#xE7;&#xF5;es r&#xE1;pidas e integradas com o sistema operacional, garantindo que o aplicativo pare&#xE7;a e se comporte como qualquer outro app nativo. Al&#xE9;m disso, o acesso a APIs nativas permite que o desenvolvedor crie funcionalidades avan&#xE7;adas com facilidade.</p>
<h3 id="4-agilidade-em-startups">4. <strong>Agilidade em Startups</strong></h3>
<p>Para startups que precisam lan&#xE7;ar rapidamente um produto no mercado, a agilidade no desenvolvimento &#xE9; crucial. O Hotwire Native permite que pequenas equipes lancem aplicativos para m&#xFA;ltiplas plataformas em um curto per&#xED;odo de tempo. Isso &#xE9; especialmente &#xFA;til em ambientes onde o tempo &#xE9; um fator essencial para garantir a competitividade no mercado.</p>
<h3 id="5-redu%C3%A7%C3%A3o-de-custos">5. <strong>Redu&#xE7;&#xE3;o de Custos</strong></h3>
<p>O desenvolvimento de aplicativos nativos para iOS e Android pode ser caro, especialmente se exigirem equipes separadas ou terceirizadas. Com o Hotwire Native, a reutiliza&#xE7;&#xE3;o de c&#xF3;digo e a simplifica&#xE7;&#xE3;o do processo de desenvolvimento resultam em uma redu&#xE7;&#xE3;o significativa de custos, tornando-o uma op&#xE7;&#xE3;o atraente para empresas que buscam efici&#xEA;ncia financeira.</p>
<h2 id="desafios-e-considera%C3%A7%C3%B5es">Desafios e Considera&#xE7;&#xF5;es</h2>
<p>Embora o Hotwire Native ofere&#xE7;a muitas vantagens, &#xE9; importante considerar que essa abordagem n&#xE3;o &#xE9; adequada para todos os casos de uso. Em alguns cen&#xE1;rios, como aplicativos com demandas gr&#xE1;ficas pesadas (jogos, por exemplo), o uso de HTML e CSS pode n&#xE3;o ser suficiente para proporcionar a performance necess&#xE1;ria. Al&#xE9;m disso, a integra&#xE7;&#xE3;o com APIs nativas pode requerer algum esfor&#xE7;o adicional em compara&#xE7;&#xE3;o com frameworks totalmente nativos como Swift ou Kotlin.</p>
<p>Outro ponto importante a considerar &#xE9; que, embora o Hotwire Native ofere&#xE7;a uma excelente solu&#xE7;&#xE3;o para muitos tipos de aplicativos, ele ainda est&#xE1; em desenvolvimento ativo e pode n&#xE3;o oferecer suporte a todas as funcionalidades e casos de uso avan&#xE7;ados que frameworks nativos oferecem.</p>
<h2 id="conclus%C3%A3o-o-futuro-do-desenvolvimento-mobile">Conclus&#xE3;o: O Futuro do Desenvolvimento Mobile</h2>
<p>O <strong>Hotwire Native</strong> apresenta uma nova abordagem para o desenvolvimento de aplicativos m&#xF3;veis, permitindo que desenvolvedores reutilizem grande parte de seu c&#xF3;digo web e ainda assim ofere&#xE7;am experi&#xEA;ncias m&#xF3;veis r&#xE1;pidas e nativas. Com sua integra&#xE7;&#xE3;o com o Turbo e o foco em uma abordagem web-first, ele tem o potencial de transformar a maneira como os aplicativos m&#xF3;veis s&#xE3;o constru&#xED;dos, especialmente para startups e empresas que buscam agilidade e efici&#xEA;ncia.</p>
<p>Se voc&#xEA; est&#xE1; considerando uma nova solu&#xE7;&#xE3;o para desenvolver seu pr&#xF3;ximo aplicativo, o Hotwire Native certamente vale a pena explorar. Com a promessa de acelerar o desenvolvimento, reduzir custos e simplificar a manuten&#xE7;&#xE3;o, ele pode ser o futuro para equipes &#xE1;geis que desejam maximizar seus recursos sem sacrificar a qualidade da experi&#xEA;ncia do usu&#xE1;rio.</p>
<p>Para mais informa&#xE7;&#xF5;es sobre o Hotwire Native, acesse o <a href="https://native.hotwired.dev/?ref=jcmaciel.com" rel="noopener">site oficial</a>.</p>]]></content:encoded></item><item><title><![CDATA[Você Deve Diversificar Suas Habilidades ou se Especializar? Descubra o Melhor Caminho para Sua Carreira na Tecnologia]]></title><description><![CDATA[<p>Imagine que voc&#xEA; est&#xE1; em uma festa p&#xF3;s-confer&#xEA;ncia de tecnologia. Em um canto, h&#xE1; uma desenvolvedora listando uma s&#xE9;rie de linguagens nas quais &#xE9; proficiente &#x2013; de Python a Rust, React a Kotlin. Em outro canto, h&#xE1; um cara mergulhado</p>]]></description><link>https://jcmaciel.com/voce-deve-diversificar-suas-habilidades-ou-se-especializar-descubra-o-melhor-caminho-para-sua-carreira-na-tecnologia/</link><guid isPermaLink="false">66f6993be60ca600013dff93</guid><dc:creator><![CDATA[José Carlos Maciel]]></dc:creator><pubDate>Fri, 27 Sep 2024 11:39:18 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1463680942456-e4230dbeaec7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHR3byUyMHdheXxlbnwwfHx8fDE3Mjc0MzcxNDd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1463680942456-e4230dbeaec7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHR3byUyMHdheXxlbnwwfHx8fDE3Mjc0MzcxNDd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Voc&#xEA; Deve Diversificar Suas Habilidades ou se Especializar? Descubra o Melhor Caminho para Sua Carreira na Tecnologia"><p>Imagine que voc&#xEA; est&#xE1; em uma festa p&#xF3;s-confer&#xEA;ncia de tecnologia. Em um canto, h&#xE1; uma desenvolvedora listando uma s&#xE9;rie de linguagens nas quais &#xE9; proficiente &#x2013; de Python a Rust, React a Kotlin. Em outro canto, h&#xE1; um cara mergulhado nas complexidades da computa&#xE7;&#xE3;o qu&#xE2;ntica, perdido em um mundo de qubits e superposi&#xE7;&#xE3;o.</p>
<p>Duas esp&#xE9;cies diferentes no ecossistema tecnol&#xF3;gico. Uma &#xE9; um canivete su&#xED;&#xE7;o, pronta para lidar com qualquer problema que apare&#xE7;a. A outra &#xE9; um laser, focada em resolver um desafio espec&#xED;fico e complexo.</p>
<p>Isso n&#xE3;o &#xE9; apenas uma cena em uma festa &#x2013; &#xE9; um retrato de um debate que vem acontecendo no mundo da tecnologia desde que as primeiras linhas de c&#xF3;digo foram escritas. Voc&#xEA; deve espalhar suas habilidades ou aprofund&#xE1;-las?</p>
<p>Essa n&#xE3;o &#xE9; apenas uma quest&#xE3;o abstrata. Sua resposta pode moldar toda a sua trajet&#xF3;ria profissional, influenciar as empresas nas quais voc&#xEA; prosperar&#xE1; e at&#xE9; mesmo determinar como voc&#xEA; enfrentar&#xE1; as tempestades em constante mudan&#xE7;a do cen&#xE1;rio tecnol&#xF3;gico.</p>
<h3 id="o-generalista-o-canivete-su%C3%AD%C3%A7o-da-tecnologia">O Generalista: O Canivete Su&#xED;&#xE7;o da Tecnologia</h3>
<p>Generalistas em tecnologia s&#xE3;o os adaptadores supremos. Eles se sentem &#xE0; vontade discutindo UI/UX com designers, debatendo arquitetura com desenvolvedores de backend e traduzindo o jarg&#xE3;o t&#xE9;cnico para a equipe de marketing.</p>
<p>Em startups, os generalistas muitas vezes s&#xE3;o os her&#xF3;is. Eles podem prototipar novas ideias rapidamente, pivotar quando necess&#xE1;rio e preencher lacunas em toda a organiza&#xE7;&#xE3;o. S&#xE3;o aqueles que conseguem ver como todas as pe&#xE7;as se encaixam e frequentemente acabam em cargos de lideran&#xE7;a.</p>
<p>Mas ser um generalista n&#xE3;o &#xE9; apenas saber um pouco de tudo. &#xC9; ser capaz de sintetizar conhecimentos de diferentes dom&#xED;nios e aplic&#xE1;-los de novas maneiras. &#xC9; sobre enxergar padr&#xF5;es e conex&#xF5;es que outros deixam passar.</p>
<h3 id="o-especialista-o-mergulhador-profundo-da-tecnologia">O Especialista: O Mergulhador Profundo da Tecnologia</h3>
<p>Especialistas s&#xE3;o aqueles que empurram os limites do que &#xE9; poss&#xED;vel. S&#xE3;o eles que fazem avan&#xE7;os em IA, revolucionam a tecnologia de banco de dados ou criam novos paradigmas de programa&#xE7;&#xE3;o.</p>
<p>Em grandes empresas de tecnologia, especialistas frequentemente lideram a inova&#xE7;&#xE3;o em &#xE1;reas espec&#xED;ficas. S&#xE3;o as pessoas de refer&#xEA;ncia quando h&#xE1; um problema complexo que precisa ser resolvido. Eles podem mergulhar fundo em quest&#xF5;es que deixariam generalistas co&#xE7;ando a cabe&#xE7;a.</p>
<p>Mas especializa&#xE7;&#xE3;o em tecnologia n&#xE3;o &#xE9; apenas saber uma coisa muito bem. &#xC9; estar na vanguarda do seu campo, antecipar para onde ele est&#xE1; indo e, &#xE0;s vezes, at&#xE9; mesmo direcionar o caminho.</p>
<h3 id="o-impacto-na-ind%C3%BAstria">O Impacto na Ind&#xFA;stria</h3>
<p>Essa divis&#xE3;o molda mais do que carreiras individuais &#x2013; ela influencia como empresas inteiras operam.</p>
<p>Considere a Apple e o Google. A Apple, conhecida por sua abordagem integrada, muitas vezes prefere generalistas que possam trabalhar em diferentes aspectos de um produto. O Google, por outro lado, tem a reputa&#xE7;&#xE3;o de contratar especialistas profundos, especialmente em &#xE1;reas como IA e algoritmos de busca.</p>
<p>E h&#xE1; a Amazon, que parece ter encontrado um equil&#xED;brio. Eles precisam de generalistas para gerenciar seu vasto ecossistema interconectado, mas tamb&#xE9;m contam com especialistas para otimizar sistemas cr&#xED;ticos, como seus algoritmos de recomenda&#xE7;&#xE3;o ou infraestrutura de nuvem.</p>
<h3 id="o-cen%C3%A1rio-em-transforma%C3%A7%C3%A3o">O Cen&#xE1;rio em Transforma&#xE7;&#xE3;o</h3>
<p>Estamos vendo a ascens&#xE3;o do que alguns chamam de profissionais em forma de &quot;T&quot; &#x2013; pessoas com conhecimento amplo em v&#xE1;rias &#xE1;reas (a barra horizontal do T) e expertise profunda em uma ou duas &#xE1;reas (a barra vertical).</p>
<p>Profissionais em forma de T s&#xE3;o canivetes su&#xED;&#xE7;os com um laser secreto e poderoso anexado.</p>
<p>Na pr&#xE1;tica, isso pode parecer com um desenvolvedor backend que conhece profundamente Java, mas tamb&#xE9;m &#xE9; capaz de discutir sobre UI/UX, arquitetura de nuvem ou an&#xE1;lise de dados. Ela n&#xE3;o est&#xE1; presa em uma &#xFA;nica &#xE1;rea &#x2013; consegue ver o panorama geral e ainda se concentrar nos detalhes quando necess&#xE1;rio.</p>
<p>Enquanto profissionais em formato T s&#xE3;o valorizados, algumas empresas agora est&#xE3;o buscando funcion&#xE1;rios em formato de &quot;V&quot;. Mas o que exatamente isso significa?</p>
<p>Diferente dos profissionais em T, que t&#xEA;m profundidade em uma &#xE1;rea e abrang&#xEA;ncia em v&#xE1;rias, os profissionais em forma de V t&#xEA;m profundidade significativa em dois dom&#xED;nios diferentes.</p>
<h3 id="a-pergunta-de-um-milh%C3%A3o-de-d%C3%B3lares">A Pergunta de Um Milh&#xE3;o de D&#xF3;lares</h3>
<p>Ent&#xE3;o, voc&#xEA; deve ser um generalista ou um especialista?</p>
<p>N&#xE3;o h&#xE1; uma resposta &#xFA;nica para todos. Depende dos seus interesses, das suas for&#xE7;as e de onde voc&#xEA; enxerga a ind&#xFA;stria caminhando.</p>
<p>Se voc&#xEA; prospera com variedade e adora ver o quadro geral, o caminho do generalista pode ser para voc&#xEA;. Talvez voc&#xEA; acabe como CTO, gerente de produto ou um desenvolvedor vers&#xE1;til que pode enfrentar qualquer projeto.</p>
<p>Os especialistas s&#xE3;o aqueles que ultrapassam os limites do poss&#xED;vel, que transformam fic&#xE7;&#xE3;o cient&#xED;fica em realidade. Eles s&#xE3;o os que fazem os carros aut&#xF4;nomos navegarem pelas ruas da cidade, que criam vacinas usando modelos computacionais, que ajudam telesc&#xF3;pios a espiar os confins mais distantes do universo.</p>
<p>Quando voc&#xEA; se especializa, n&#xE3;o est&#xE1; apenas aprendendo uma habilidade &#x2013; est&#xE1; embarcando em uma jornada. Est&#xE1; dizendo: &#x201C;Este &#xE9; o meu Everest, e eu vou escal&#xE1;-lo.&#x201D; N&#xE3;o &#xE9; sempre um caminho f&#xE1;cil, mas para aqueles que amam a emo&#xE7;&#xE3;o da descoberta, que sentem adrenalina ao resolver problemas aparentemente imposs&#xED;veis, &#xE9; uma aventura como nenhuma outra.</p>
<p>Ent&#xE3;o, se voc&#xEA; se v&#xEA; obcecado pelas min&#xFA;cias da computa&#xE7;&#xE3;o qu&#xE2;ntica, ou perdendo o sono pensando em como tornar a IA mais &#xE9;tica, ou esbo&#xE7;ando ideias para a pr&#xF3;xima gera&#xE7;&#xE3;o de arquitetura de nuvem &#x2013; mergulhe nisso. Essa paix&#xE3;o pode ser seu superpoder, seu bilhete para deixar uma marca duradoura no mundo da tecnologia.</p>]]></content:encoded></item></channel></rss>