<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Guilherme Yamakawa de Oliveira</title>
    <description>The latest articles on Forem by Guilherme Yamakawa de Oliveira (@guilherme44).</description>
    <link>https://forem.com/guilherme44</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30816%2F90a4981b-417b-4d41-ac2c-4be6e1433b90.jpg</url>
      <title>Forem: Guilherme Yamakawa de Oliveira</title>
      <link>https://forem.com/guilherme44</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/guilherme44"/>
    <language>en</language>
    <item>
      <title>pluck vs. select</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Thu, 06 Oct 2022 09:49:29 +0000</pubDate>
      <link>https://forem.com/guilherme44/pluck-vs-select-2p8g</link>
      <guid>https://forem.com/guilherme44/pluck-vs-select-2p8g</guid>
      <description>&lt;h2&gt;
  
  
  pluck
&lt;/h2&gt;

&lt;p&gt;In Rails, we have pluck, which returns an array with the values of the attributes you selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you pass more than one attribute, the pluck returns an array of multiple attributes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"updated_at"&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Wed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="no"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;27.924159000&lt;/span&gt; &lt;span class="no"&gt;EST&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Tue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="no"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;30.056920000&lt;/span&gt; &lt;span class="no"&gt;EST&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Thu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="no"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;29.238601000&lt;/span&gt; &lt;span class="no"&gt;EDT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Thu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="no"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;29.251257000&lt;/span&gt; &lt;span class="no"&gt;EDT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Sat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="no"&gt;Jun&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;41.536687000&lt;/span&gt; &lt;span class="no"&gt;EDT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Tue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="no"&gt;Jun&lt;/span&gt; &lt;span class="mi"&gt;2022&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;45.091360000&lt;/span&gt; &lt;span class="no"&gt;EDT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query is precise to get only the attributes you are asking for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nv"&gt;"doctors"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"doctors"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"updated_at"&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"doctors"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  select
&lt;/h2&gt;

&lt;p&gt;The select make the same query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;Doctor&lt;/span&gt; &lt;span class="no"&gt;Load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"updated_at"&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;

&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"updated_at"&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;Doctor&lt;/span&gt; &lt;span class="no"&gt;Load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"updated_at"&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"doctors"&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2ec40 id: 1, updated_at: Wed, 23 Jan 2019 11:44:27.924159000 EST -05:00&amp;gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2eab0 id: 3, updated_at: Tue, 29 Jan 2019 15:47:30.056920000 EST -05:00&amp;gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2e998 id: 7, updated_at: Thu, 28 May 2020 19:30:29.238601000 EDT -04:00&amp;gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2e858 id: 8, updated_at: Thu, 28 May 2020 19:30:29.251257000 EDT -04:00&amp;gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2e4c0 id: 9, updated_at: Sat, 26 Jun 2021 19:56:41.536687000 EDT -04:00&amp;gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;#&amp;lt;Doctor:0x0000000111a2e218 id: 5, updated_at: Tue, 28 Jun 2022 16:49:45.091360000 EDT -04:00&amp;gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But select returns an ActiveRecord_Relation with objects from the model where it was called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Doctor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActiveRecord_Relation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that's all folks :)&lt;/p&gt;

</description>
      <category>rails</category>
      <category>activerecord</category>
    </item>
    <item>
      <title>[PT-BR] Organizando flash messages no Phoenix</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Sun, 16 Feb 2020 18:30:27 +0000</pubDate>
      <link>https://forem.com/guilherme44/pt-br-organizando-flash-messages-no-phoenix-j1c</link>
      <guid>https://forem.com/guilherme44/pt-br-organizando-flash-messages-no-phoenix-j1c</guid>
      <description>&lt;p&gt;Bom, comecei a fazer um sistema para entender melhor como funciona &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt; e aprender sobre o &lt;a href="https://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt; é um framework para &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt;, assim como o &lt;a href="https://rubyonrails.org/"&gt;Rails&lt;/a&gt; é um framework para o &lt;a href="https://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, ele tem como missão ser um framework produtivo e que não compromete a velocidade ou a capacidade de manutenção.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, decidi criar um CRUD simples em &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt; para eu registrar os livros que eu já li, utilizei os seguintes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cria a aplicação.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mix phx.new booklistx

&lt;span class="c"&gt;# Entra no projeto criado&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;booklistsx

&lt;span class="c"&gt;# Gerador do CRUD (estilo scaffold do rails)&lt;/span&gt;
mix phx.gen.html Books Book books title:string

&lt;span class="c"&gt;# Cria o banco e cria a tabela de books&lt;/span&gt;
mix ecto.create
mix ecto.migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defini como root da aplicação ser a listagem de livros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lib/booklistx_web/router.ex&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:router&lt;/span&gt;

  &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="ss"&gt;:browser&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:accepts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:fetch_session&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:fetch_flash&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:protect_from_forgery&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:put_secure_browser_headers&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:accepts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;pipe_through&lt;/span&gt; &lt;span class="ss"&gt;:browser&lt;/span&gt;

    &lt;span class="c1"&gt;# get "/", PageController, :index # &amp;lt;- Comentei essa linha!&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;BooksController&lt;/span&gt;    &lt;span class="c1"&gt;# &amp;lt;- Adicionei essa linha!&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Other scopes may use custom stacks.&lt;/span&gt;
  &lt;span class="c1"&gt;# scope "/api", BooklistxWeb do&lt;/span&gt;
  &lt;span class="c1"&gt;#   pipe_through :api&lt;/span&gt;
  &lt;span class="c1"&gt;# end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executei o comando para iniciar a aplicação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix phx.server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WwTc2BtG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hu9jspp48viwq06dpf2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WwTc2BtG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hu9jspp48viwq06dpf2g.png" alt="Alt Text" width="817" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após isso estava pronto eu já podia adicionar livros e remover livros, foi ai que quando criei um livro mostrava uma flash message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtlPTTGs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/blagx209x29io841dqom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtlPTTGs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/blagx209x29io841dqom.png" alt="Alt Text" width="829" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Utilizei o inspetor do browser para ver como era o html.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ur2mq73n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s99k9qrskxkg8fy1ek0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ur2mq73n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s99k9qrskxkg8fy1ek0.png" alt="Alt Text" width="591" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ví que o html sempre vinha com as tags html de flash message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-info"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Book updated successfully.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tem apenas um truque simples de css para não mostrar nada caso não houver nenhum conteúdo na tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* assets/css/phoenix.css */&lt;/span&gt;

&lt;span class="nc"&gt;.alert&lt;/span&gt;&lt;span class="nd"&gt;:empty&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por padrão o arquivo vem assim, carregando as tags de alert mesmo que não tenha nenhuma flash message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight eex"&gt;&lt;code&gt;# lib/booklistx_web/layout/app.html.exx

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Booklistx · Phoenix Framework&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/css/app.css"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;csrf_meta_tag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"navigation"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://hexdocs.pm/phoenix/overview.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Started&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://phoenixframework.org/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phx-logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/images/phoenix.png"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Phoenix Framework Logo"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
#-&amp;gt;   &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-info"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;get_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
#-&amp;gt;   &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;get_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="nv"&gt;@view_module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;@view_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;assigns&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/js/app.js"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso estava me incomodando, pesquisei sobre como funciona e encontrei em uma issue sugerindo para utilizar da seguinte forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight eex"&gt;&lt;code&gt;# lib/booklistx_web/layout/app.html.exx
...
&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-info"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele só vai mostrar agora caso tenha alguma flash message, porem essas variaveis no meio do código não ficou legal &lt;code&gt;info&lt;/code&gt; e &lt;code&gt;error&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Decidi fazer algo parecido com o que já fiz no Rails.&lt;/p&gt;

&lt;p&gt;Acredito que deve ter várias outras formas de resolver isso e que deve ser melhor, porem essa foi a que eu mais gostei porque é simples e utiliza os conceitos que eu venho estudando.&lt;/p&gt;

&lt;p&gt;Criei os seguintes arquivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cria o arquivo shared_view&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;lib/booklistx_web/shared_view.ex
&lt;span class="c"&gt;# Cria a pasta shared&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;lib/booklistx_web/templates/shared
&lt;span class="c"&gt;# Cria o arquivo _flash_message.html.exx&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;lib/booklistx_web/templates/shared/_flash_message.html.eex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lib/booklistx_web/shared_view.ex&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;SharedView&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:view&lt;/span&gt;
  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Helpers&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;show_flash_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;get_flash&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;flash_message&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;flash_message&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s2"&gt;"_flash_message.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class:&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;flash_message&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s2"&gt;"_flash_message.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class:&lt;/span&gt; &lt;span class="s2"&gt;"danger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;flash_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui eu estou utilizando coisas que eu aprendi como pipe e pipeline no método &lt;code&gt;show_flash_message&lt;/code&gt; e pattern matching para o método &lt;code&gt;flash_message&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Já a partial ficou da seguinte forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight eex"&gt;&lt;code&gt;# lib/booklistx_web/templates/shared/_flash_message.html.eex

&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="nv"&gt;@class&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="nv"&gt;@message&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O nosso layout ficou da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight eex"&gt;&lt;code&gt;# lib/booklistx_web/layout/app.html.exx

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Booklistx · Phoenix Framework&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/css/app.css"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;csrf_meta_tag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"navigation"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://hexdocs.pm/phoenix/overview.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Started&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://phoenixframework.org/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phx-logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/images/phoenix.png"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Phoenix Framework Logo"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;BooklistxWeb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;SharedView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show_flash_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;

      &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="nv"&gt;@view_module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;@view_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;assigns&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/js/app.js"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;No meu ponto de vista, ficou bem melhor do que utilizarmos as variáveis (&lt;code&gt;info&lt;/code&gt; e &lt;code&gt;error&lt;/code&gt;) e aqueles IF direto no layout, acredito que deve ter soluções melhores, mas essa foi a que eu consegui fazer e mais me agradou. Consegui colocar em pratica algumas coisas que aprendi como o pipe, pipeline e pattern matching.&lt;/p&gt;

&lt;p&gt;Vou deixar o link desse código que eu fiz no github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/guilhermeyo/booklistx"&gt;https://github.com/guilhermeyo/booklistx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fique a vontade para deixar um feedback e melhorias que posso realizar.&lt;/p&gt;




&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://elixircasts.io/partial-templates-with-phoenix"&gt;#23: Partial Templates with Phoenix&lt;/a&gt;&lt;br&gt;
&lt;a href="https://elixirforum.com/t/check-for-error-and-info-alert-in-phoenix/1984/"&gt;Elixir forum - Check for error and info alert in Phoenix&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/phoenixframework/phoenix/issues/1757"&gt;Issue phoenixframework - Add has_flash? functions. #1757&lt;/a&gt;&lt;/p&gt;

</description>
      <category>phoenix</category>
      <category>elixir</category>
      <category>myelixirstatus</category>
    </item>
    <item>
      <title>[PT-BR] Instalando Elixir com ASDF</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Mon, 10 Feb 2020 02:09:26 +0000</pubDate>
      <link>https://forem.com/guilherme44/pt-br-instalando-elixir-com-asdf-277h</link>
      <guid>https://forem.com/guilherme44/pt-br-instalando-elixir-com-asdf-277h</guid>
      <description>&lt;p&gt;Estou me aventurando no &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt;, mas antes de começar a fazer algo precisei instalar Elixir, como utilizo o &lt;a href="https://asdf-vm.com/"&gt;asdf&lt;/a&gt; para gerenciar versões de linguagem, escrevi como eu fiz no meu computador.&lt;/p&gt;

&lt;p&gt;Se você quiser saber mais sobre o asdf, eu falei sobre ele no meu primeiro post.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:4000/2019/03/configurando-ruby-e-node-com-asdf.html"&gt;Configurando Ruby e Node.js com ASDF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pra quem não sabe o &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt; é uma linguagem de programação open-source criada pelo &lt;a href="https://twitter.com/josevalim"&gt;José Valim&lt;/a&gt; na Plataformatec (empresa que foi comprada pelo &lt;a href="https://nubank.com.br/"&gt;Nubank&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Elixir é uma linguagem moderna, dinâmica e funcional. Utiliza VM Erlang, conhecida por executar sistemas de baixa latência, concorrência, tolerância a falha, distrubuição e escalabilidade (&lt;a href="https://elixir-lang.org/"&gt;Mais informaçoes&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Vamos lá.&lt;/p&gt;

&lt;p&gt;Para começar precisamos de instalar o asdf, é algo bem fácil, é só seguir o tutorial da página do projeto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asdf-vm.com/#/core-manage-asdf-vm?id=install-asdf-vm"&gt;Tutorial para instalar o asdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o asdf instalado e configurado, precisamos de instalar algumas dependências do Erlang.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# OSX
$ brew install autoconf

---

# Ubuntu / Debian
$ sudo apt-get -y install build-essential autoconf m4 libncurses5-dev libwxgtk3.0-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em outros sistemas operacionais eu não sei instalar com o asdf, porem é possível instalar Elixir de alguma forma, seja por docker ou algum executável.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elixir-lang.org/install.html"&gt;Outras opções e outros SO&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Agora estamos preparados para instalar o Erlang.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Adiciona o plugin de Erlang aonde tem todas as versões disponíveis.
$ asdf plugin-add erlang

# Mostra todas as versões disponíveis de Erlang.
$ asdf list-all erlang

# Instala o Erlang.
$ asdf install erlang 22.2.2

# Definimos a versão padrão do Erlang no SO.
$ asdf global erlang 22.2.2

# Pode demorar um pouco, pois vai compilar o Erlang.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de prosseguirmos com a instalação do Elixir, é importante entender como as versões dos dois funcionam juntas ou não.&lt;/p&gt;

&lt;p&gt;A versão do Erlang é frequentemente chamada de versão OTP. A versão do Elixir usada deve ser compilada especificamente para a versão do Erlang em uso.&lt;/p&gt;

&lt;p&gt;Caso você utilize uma versão do Elixir compilada com uma versão diferente da versão (OTP) do Erlang, você pode ter problemas.&lt;/p&gt;

&lt;p&gt;A versão que instalamos é a 22, caso você quer verificar a versão pelo console é bem simples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVvPZA49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v8awuc76s19rgqq34bm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVvPZA49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v8awuc76s19rgqq34bm7.png" alt="command erl return" width="762" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que confirmamos que é o OTP-22 vamos instalar o Elixir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Adiciona o plugin de Elixir aonde tem todas as versões disponíveis.
$ asdf plugin-add elixir

# Mostra todas as versões disponíveis de Elixir.
$ asdf list-all elixir

# Instala o Elixir.
$ asdf install elixir 1.9.4-otp-22

# Definimos a versão padrão do Elixir no SO.
$ asdf global elixir 1.9.4-otp-22

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bom agora vamos executar o comando &lt;code&gt;elixir -v&lt;/code&gt; e confirmar as versões de ambos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vZ6C353V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2kgbq35g26oiouwgdasn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vZ6C353V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2kgbq35g26oiouwgdasn.png" alt="command elixir -v return" width="772" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após confirmar as versões é só executar o comando &lt;code&gt;iex&lt;/code&gt; e ver se está tudo ok.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DFcgkVBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zyc2eop5yw7becigdevm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DFcgkVBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zyc2eop5yw7becigdevm.png" alt="command iex return" width="772" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Tem &lt;a href="https://elixir-lang.org/install.html"&gt;outras formas&lt;/a&gt; de instalar o Elixir, porem gosto de deixar tudo que for possível concentrado no asdf como ruby, node, elixir, erlang, python, entre outras.&lt;/p&gt;

&lt;p&gt;Ouço falar do &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt; desde quando surgiu e fiz pequenas coisas para brincar, porem nunca me aventurei de verdade e o que mais me motivou além do tanto de oportunidades de trabalho que vem surgindo no Brasil e no mundo, é a comunidade do Brasil e do mundo, todos são muito receptivos e adeptos a diversidade, o que no meu ponto de vista é tudo que precisa para fomentar e fazer a linguagem crescer cada vez mais.&lt;/p&gt;




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://elixir-lang.org/install.html"&gt;Documentação oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elixircasts.io/installing-elixir-with-asdf"&gt;Elixir Casts - Installing Elixir with asdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thinkingelixir.com/install-elixir-using-asdf/#Install_Erlang"&gt;Thinking Elixir - Install Elixir using asdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agradecimentos:&lt;/p&gt;

&lt;p&gt;Muito obrigado &lt;a href="https://twitter.com/adolfont"&gt;Adolfo Neto&lt;/a&gt;, por me dar esse feedback importante sobre o OTP do Erlang e me passar o site &lt;a href="https://thinkingelixir.com/"&gt;Thinking Elixir&lt;/a&gt;, com certeza vou acompanhar.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>myelixirstatus</category>
      <category>beginners</category>
      <category>erlang</category>
    </item>
    <item>
      <title>[PT-BR] Utilizando o MinIO no Rails</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Sun, 09 Feb 2020 14:41:54 +0000</pubDate>
      <link>https://forem.com/guilherme44/pt-br-utilizando-o-minio-no-rails-ml8</link>
      <guid>https://forem.com/guilherme44/pt-br-utilizando-o-minio-no-rails-ml8</guid>
      <description>&lt;p&gt;Estou em um projeto aonde a configuração de upload de arquivos utilizada é o Active Storage com o Amazon S3. Porem&lt;br&gt;
não tem nenhuma configuração feita para eu baixar os arquivos do S3 e utilizar eles em desenvolvimento.&lt;/p&gt;

&lt;p&gt;Quando olhei a configuração do arquivo &lt;code&gt;config/storage.yml&lt;/code&gt; vi a seguinte configuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Disk&lt;/span&gt;
  &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.root.join("storage") %&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logo pensei que seria algo simples, apenas precisava trazer tudo que tem dentro do Bucket do S3 para dentro da minha pasta &lt;code&gt;app/storage&lt;/code&gt; da aplicação.&lt;/p&gt;

&lt;p&gt;Baixei o AWS-CLI e configurei com as minhas credenciais.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sJwAatW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s7urc4wsmh5946rwu1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sJwAatW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9s7urc4wsmh5946rwu1x.png" alt="Configuration AWS" width="809" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após isso sincronizei os arquivos do S3 na minha pasta de &lt;code&gt;app/storage&lt;/code&gt; com o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;sync &lt;/span&gt;s3://bucket-name ~/Projects/selected-project/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Iniciei a aplicação e não deu certo 🙄.&lt;/p&gt;

&lt;p&gt;No ActiveStorage quando o service configurado é Disk após o blob gerar a key o arquivo é salvo dentro de duas pastas e depois a key do blob.&lt;/p&gt;

&lt;p&gt;Procurei o path do arquivo pelo console e ele me retornou o path seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; user &lt;span class="o"&gt;=&lt;/span&gt; User.first
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ActiveStorage::Blob.service.send&lt;span class="o"&gt;(&lt;/span&gt;:path_for, u.avatar.key&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"storage/jt/Y7/jtY7656jGPvfPMUUA8kX6Vb4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notei que essas pastas criadas era os 4 primeiros caracteres da key.&lt;/p&gt;

&lt;p&gt;Pensei em algumas soluções:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Escrever um script para gerar essas sub-pastas e adicionar os arquivos nelas.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Não optei por essa opção, talvez ela poderia não funcionar e como não tenho experiencia com scripts em alterar o filesystem, achei que iria demorar muito com isso.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verificar como o Active Storage gera esse path_for e falar pra ele gerar direto sem essas sub-pastas.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Pesquisei e não encontrei nenhum lugar aonde e conseguisse fazer isso.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duplicar o bucket dentro do S3 e utilizar ele para desenvolvimento.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Não gostei dessa ideia pois iria ter que pagar o armazenamento de 2 buckets.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilizar o &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;br&gt;
Foi a opção que acreditei ser mais rapída e com melhor custo x benefício.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O MinIO pra quem não conhece é um projeto Open Source em &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; e foi projetado desde o início para ser o padrão no armazenamento de objetos na nuvem privada. Ele é um servidor de objetos nativo da nuvem com desempenho simultâneo, escalável e leve (&lt;a href="https://min.io/product/overview"&gt;Mais informações&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Assim preciso configurar o &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt; igual funciona o S3 pois minha aplicação precisa pensar que está no S3.&lt;br&gt;
Baixei o &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt; pelo site deles e configurei as variaveis de ambiente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MINIO_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"minio_storage_development"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MINIO_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"minio_storage_development"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MINIO_REGION_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele é configurado através das variáveis de ambientes. Você pode verificar quais são todas as configurações pela documentação dele. (&lt;a href="https://docs.min.io/"&gt;Documentação MinIO&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Agora é apenas iniciar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;minio server ~/minio_storage

Endpoint:  http://xxx.xxx.xxx.xxx:9000  http://xxx.xxx.xxx.xxx:9000  http://127.0.0.1:9000
AccessKey: minio_storage_development
SecretKey: minio_storage_development
Region:    us-east-1

Browser Access:
  http://xxx.xxx.xxx.xxx:9000  http://xxx.xxx.xxx.xxx:9000  http://127.0.0.1:9000

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
  &lt;span class="nv"&gt;$ &lt;/span&gt;mc config host add myminio http://100.100.101.162:9000 minio_storage_development minio_storage_development
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obs: Escondi o meu IP com o xxx.xxx.xxx.xxx pois ele é fixo e não quero deixar exposto para a Web.&lt;/p&gt;

&lt;p&gt;Pronto temos um servidor &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt; configurado rodando no seu computador.&lt;/p&gt;

&lt;p&gt;Acessei ele através do meu navegador &lt;a href="http://127.0.0.1:9000/"&gt;http://127.0.0.1:9000/&lt;/a&gt; utilizando a Access Key e Secret Key e criei um Bucket chamado &lt;code&gt;rails_app_bucket&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nas configurações do rails que fica em &lt;code&gt;config/storage.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;S3&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:9000&lt;/span&gt;
  &lt;span class="na"&gt;access_key_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minio_storage_development&lt;/span&gt;
  &lt;span class="na"&gt;secret_access_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minio_storage_development&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
  &lt;span class="na"&gt;bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails_app_bucket&lt;/span&gt;
  &lt;span class="na"&gt;force_path_style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Movi os arquivos todos os arquivos que tinha baixado do Bucket do S3 para a pasta do Bucket &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; ~/Projects/selected-project/storage/&lt;span class="k"&gt;*&lt;/span&gt; ~/minio_storage/rails_app_bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora para sincronizar os arquivos do S3 utilizo o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws s3 &lt;span class="nb"&gt;sync &lt;/span&gt;s3://bucket-name ~/minio_storage/rails_app_bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também deixei configurado no meu &lt;code&gt;Procfile.development&lt;/code&gt; para iniciar o servidor do &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt; sempre que inicio a minha aplicação pelo foreman ficando assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Procfile.development

server: bin/rails server
webpacker: bin/webpack-dev-server
redis: redis-server
sidekiq: bundle exec sidekiq
minio: minio server ~/minio_storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Ficou muito simples para eu conseguir sincronizar os arquivos e não aparecer nenhum 404 de arquivos quando eu estou rodando aplicação, e muito menos algum erro do rails que mostrando que o arquivo não existe.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>minio</category>
      <category>s3</category>
    </item>
    <item>
      <title>[PT-BR] Configurando ReactJS no Rails com o Webpacker</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Thu, 06 Feb 2020 23:04:48 +0000</pubDate>
      <link>https://forem.com/guilherme44/pt-br-configurando-reactjs-no-rails-com-o-webpacker-1jkd</link>
      <guid>https://forem.com/guilherme44/pt-br-configurando-reactjs-no-rails-com-o-webpacker-1jkd</guid>
      <description>&lt;p&gt;O Javascript moderno usa muitas bibliotecas e estruturas de processamento, incluindo NPM, Yarn e Webpack. Então, quando você usa o React, você precisa de todas essas ferramentas. O Rails tem asset pipeline há muito tempo e usou o Sprockets como a principal ferramenta.&lt;/p&gt;

&lt;p&gt;Desde o Rails 5.1 existe uma alternativa ao Sprockets para Javascript, o Webpacker e no Rails 6.0, o Webpacker será o padrão. O Webpacker usa o Webpack para compilar todos os seus arquivos Javascript.&lt;/p&gt;

&lt;p&gt;Uma das grandes vantagens do Webpack é que, em seu ambiente de desenvolvimento, ele oferece a opção de compilação ao vivo do Javascript via webpack-dev-server. Isso significa que você altera um arquivo e ele é automaticamente compilado e até mesmo enviado para o navegador. Isso permite um desenvolvimento muito rápido. É claro que, em produção, você deseja usar pré-compilação, compilando todos os arquivos Javascript em apenas um reduzido.&lt;/p&gt;

&lt;p&gt;Aqui vou mostrar como criar uma aplicação Ruby on Rails do zero com Webpacker e configurar o ReactJS através do Webpacker.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que vamos precisar?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Ruby 2.5.1 ou superior&lt;/li&gt;
&lt;li&gt;Rails 5.2.1 ou superior&lt;/li&gt;
&lt;li&gt;Webpacker 3.5.5 ou superior&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Criando aplicação
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new rails-com-reactjs --skip-test --webpack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Este comando cria o aplicativo e configura o Webpacker. Ele ignora a estrutura de testes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec rails webpacker:install:react
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Este comando instala e configura o ReactJS da seguinte forma:&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adiciona as configurações do babel no root&lt;/li&gt;
&lt;li&gt;Cria um exemplo em &lt;code&gt;app/javascript/packs/hello_react.jsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Atualiza as configurações do Webpacker para aceitar arquivos com a extensão &lt;code&gt;.jsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Instala todas as dependencias que o React precisa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O exemplo criado &lt;code&gt;hello_react.jsx&lt;/code&gt; insere um componente direto no &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; da aplicação, achei isso sem sentido, sem nenhuma estrutura, e se utilizarmos vai aparecer em todas as páginas, por isso eu sempre o ignoro e utilizo uma estrutura de pastas separando todos os componentes React dentro dela e para usar um componente eu utilizo um helper da &lt;code&gt;gem 'react-rails'&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando o ReactJS
&lt;/h2&gt;

&lt;p&gt;Adicione no seu &lt;code&gt;Gemfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'react-rails'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Após salvar o arquivo não esqueça de executar o comando &lt;code&gt;bundle install&lt;/code&gt; para baixar e instalar a gem na aplicação.&lt;/p&gt;

&lt;p&gt;Instale o &lt;code&gt;react_ujs&lt;/code&gt; com o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react_ujs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;react_ujs&lt;/code&gt; é um driver do &lt;code&gt;react-rails&lt;/code&gt; ele varrerá a página e montará os componentes usando &lt;code&gt;data-react-class&lt;/code&gt; e &lt;code&gt;data-react-props&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora vamos criar uma estrutura bem simples para deixarmos os componentes organizados e criar o nosso componente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir app/javascript/components
touch app/javascript/components/hello_world.jsx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Dentro do arquivo &lt;code&gt;hello_world.jsx&lt;/code&gt; adicione o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Para conseguirmos chamar o componente de dentro de uma página precisamos adicionar as seguintes configurações no final do arquivo:&lt;br&gt; &lt;code&gt;app/javascript/packs/application.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentRequireContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ReactRailsUJS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react_ujs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;ReactRailsUJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;componentRequireContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;No arquivo:&lt;br&gt; &lt;code&gt;app/views/layouts/application.html.erb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Remova o javascript do asset pipeline.
&amp;lt;%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %&amp;gt;

# Adicione o javascript do webpacker.
&amp;lt;%= javascript_pack_tag 'application' %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilizando o componente nas views
&lt;/h2&gt;

&lt;p&gt;Agora vamos criar uma página para a mágica acontecer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g controller pages index --no-helper --no-assets --no-controller-specs --no-view-specs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Este comando cria um controller chamado pages e uma action index. Ele ignora a estrutura de testes, assets e helpers.&lt;/p&gt;

&lt;p&gt;No arquivo:&lt;br&gt; &lt;code&gt;config/routes.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Remover&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'pages/index'&lt;/span&gt;

&lt;span class="c1"&gt;# Adicionar&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="s1"&gt;'pages#index'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Chame na view o componente com o helper do &lt;code&gt;react-rails&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;app/views/pages/index.html.erb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;react_component&lt;/span&gt; &lt;span class="s1"&gt;'hello_world'&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Na hora de iniciar a aplicação utilize o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em outra aba do terminal execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/webpack-dev-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pronto, agora você pode criar componentes com ReactJS para auxiliar você no desenvolvimento da sua aplicação Rails, sem ter que utilizar o React como um Single Page Application.&lt;/p&gt;

&lt;p&gt;Coloquei o exemplo do código feito no Github:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/guilhermeyo/rails-com-reactjs"&gt;https://github.com/guilhermeyo/rails-com-reactjs&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rails/webpacker"&gt;Documentação oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reactjs/react-rails"&gt;Documentação da gem react-rails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>react</category>
      <category>reactrails</category>
    </item>
    <item>
      <title>[PT-BR] Enviando SMS com Ruby com o Twilio</title>
      <dc:creator>Guilherme Yamakawa de Oliveira</dc:creator>
      <pubDate>Thu, 06 Feb 2020 00:56:05 +0000</pubDate>
      <link>https://forem.com/guilherme44/pt-br-enviando-sms-com-ruby-com-o-twilio-4j33</link>
      <guid>https://forem.com/guilherme44/pt-br-enviando-sms-com-ruby-com-o-twilio-4j33</guid>
      <description>&lt;p&gt;Eu nunca havia feito uma aplicação que fosse necessario enviar SMS para alguém, mas o último projeto que fizemos na firma precisou, conversei com um amigo sobre o assunto e ele me falou do &lt;a href="http://twilio.com" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt;, fiz uma pesquisa rápida sobre e achei a documentação bem completa e fácil de implementar.&lt;/p&gt;

&lt;p&gt;Para quem não conhece o &lt;a href="http://twilio.com" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt;, ele é uma plataforma que possibilita integrar voz, mensagens de texto, vídeo, notificações entre outras facilidades na sua aplicação, através de uma API. As integrações são feitas com Ruby, Java, .NET, Node.js, PHP, entre outras.&lt;/p&gt;

&lt;p&gt;Vou mostrar como é fácil enviar SMS pelo console do ruby e em breve pretendo fazer um screencast de como implementar essa funcionalidade em uma aplicação Ruby on Rails.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 1 - Criar conta no Twilio:
&lt;/h3&gt;

&lt;p&gt;Crie uma conta no Twilio e acesse o &lt;a href="http://twilio.com/console" rel="noopener noreferrer"&gt;Console do Twilio&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Criar conta: &lt;a href="https://www.twilio.com/try-twilio" rel="noopener noreferrer"&gt;https://www.twilio.com/try-twilio&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Console: &lt;a href="http://twilio.com/console" rel="noopener noreferrer"&gt;http://twilio.com/console&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao criar a conta, é disponibilizado um Trial para realizar testes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F12pjx8jk6915y7d36d1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F12pjx8jk6915y7d36d1h.png" alt="Twilio credentials"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não esqueça de &lt;a href="https://www.twilio.com/console/phone-numbers/verified" rel="noopener noreferrer"&gt;cadastrar número verificado&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://www.twilio.com/console/phone-numbers/verified" rel="noopener noreferrer"&gt;https://www.twilio.com/console/phone-numbers/verified&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Observações:&lt;/strong&gt; Os números verificados são obrigatórios para você conseguir enviar SMS com TRIAL.&lt;/p&gt;
&lt;h3&gt;
  
  
  Passo 2 - Enviar a SMS:
&lt;/h3&gt;

&lt;p&gt;Instale a gem do Twilio com o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem install twilio-ruby -v 5.21.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abra um console ruby com o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;irb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro do console nós importamos a gem "twilio-ruby", configuramos as variavéis e enviamos uma mensagem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'twilio-ruby'&lt;/span&gt;

&lt;span class="c1"&gt;# Pegue seu SID e Auth Token de twilio.com/console&lt;/span&gt;
&lt;span class="c1"&gt;# PERIGO! Isso é inseguro.&lt;/span&gt;
&lt;span class="n"&gt;account_sid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'&lt;/span&gt;
&lt;span class="n"&gt;auth_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'seu_auth_token'&lt;/span&gt;
&lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'seu_numero'&lt;/span&gt; &lt;span class="c1"&gt;# Número que você alugou no twilio&lt;/span&gt;
&lt;span class="vi"&gt;@client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Twilio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;REST&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mensagem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# +15017122661&lt;/span&gt;
  &lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="s1"&gt;'Minha primeira mensagem enviada com ruby.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'+5544999801281'&lt;/span&gt; &lt;span class="c1"&gt;# +5544998761234&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sid&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lembrando que isso é uma maneira insegura. É importante manter as credenciais, como o SID e o Auth Token, armazenando-as de maneira a impedir o acesso não autorizado.&lt;br&gt;
Como é apenas um exemplo para testes utilizei elas no console mesmo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finalizando
&lt;/h3&gt;

&lt;p&gt;Como você pode ver é muito fácil sair enviando SMS com Ruby.&lt;/p&gt;

&lt;p&gt;O &lt;a href="http://twilio.com" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt; oferece muitos outros serviços e você pode ver e consultar o preço de todos acessando &lt;a href="https://www.twilio.com/pricing" rel="noopener noreferrer"&gt;https://www.twilio.com/pricing&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>twilio</category>
      <category>sms</category>
    </item>
  </channel>
</rss>
