<?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>DEV Community: Francisco Quintero 🇨🇴</title>
    <description>The latest articles on DEV Community by Francisco Quintero 🇨🇴 (@cescquintero).</description>
    <link>https://dev.to/cescquintero</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%2F96875%2F6ffdca48-d08e-46bb-a751-eaf55711b5e5.jpg</url>
      <title>DEV Community: Francisco Quintero 🇨🇴</title>
      <link>https://dev.to/cescquintero</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cescquintero"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Fri, 26 Sep 2025 16:29:45 +0000</pubDate>
      <link>https://dev.to/cescquintero/-49l1</link>
      <guid>https://dev.to/cescquintero/-49l1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ankitmalikg/how-to-stop-homebrew-auto-update-on-mac-terminal-hb0" class="crayons-story__hidden-navigation-link"&gt;How to stop Homebrew auto update on mac terminal&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/ankitmalikg" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F697325%2Fb7604217-a4e4-4b07-9ae5-cac52846f252.png" alt="ankitmalikg profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ankitmalikg" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ankit malik
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ankit malik
                
              
              &lt;div id="story-author-preview-content-1391601" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ankitmalikg" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F697325%2Fb7604217-a4e4-4b07-9ae5-cac52846f252.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ankit malik&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/ankitmalikg/how-to-stop-homebrew-auto-update-on-mac-terminal-hb0" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 7 '23&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/ankitmalikg/how-to-stop-homebrew-auto-update-on-mac-terminal-hb0" id="article-link-1391601"&gt;
          How to stop Homebrew auto update on mac terminal
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mac"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mac&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/homebrew"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;homebrew&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/ankitmalikg/how-to-stop-homebrew-auto-update-on-mac-terminal-hb0" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;27&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ankitmalikg/how-to-stop-homebrew-auto-update-on-mac-terminal-hb0#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>mac</category>
      <category>homebrew</category>
    </item>
    <item>
      <title>Para poder configurar Sidekiq como demonio usando Systemd.</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Fri, 28 Feb 2025 16:18:26 +0000</pubDate>
      <link>https://dev.to/cescquintero/para-poder-configurar-sidekiq-como-demonio-usando-systemd-54gg</link>
      <guid>https://dev.to/cescquintero/para-poder-configurar-sidekiq-como-demonio-usando-systemd-54gg</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/kevinluo201" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F283252%2F07012131-5bb5-4aff-b73c-0dbd85e2439f.png" alt="kevinluo201"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/kevinluo201/start-sidekiq-6-as-daemon-in-production-environment-on-ubuntu-20-04-4m7b" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Run Sidekiq 6 as daemon in Production environment on Ubuntu 20.04&lt;/h2&gt;
      &lt;h3&gt;Kevin Luo ・ Aug 20 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#sidekiq&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rails&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#systemd&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>sidekiq</category>
      <category>rails</category>
      <category>systemd</category>
    </item>
    <item>
      <title>Olis</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Fri, 28 Feb 2025 02:26:01 +0000</pubDate>
      <link>https://dev.to/cescquintero/olis-4ean</link>
      <guid>https://dev.to/cescquintero/olis-4ean</guid>
      <description></description>
    </item>
    <item>
      <title>No sabía que había "trinos" en Dev!</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Wed, 22 Jan 2025 15:09:04 +0000</pubDate>
      <link>https://dev.to/cescquintero/no-sabia-que-habia-trinos-en-dev-2pfc</link>
      <guid>https://dev.to/cescquintero/no-sabia-que-habia-trinos-en-dev-2pfc</guid>
      <description></description>
      <category>spanish</category>
    </item>
    <item>
      <title>He estado haciendo degoogle desde el año pasado y esto es algo que me hubiera gustado saber.</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Wed, 22 Jan 2025 15:08:37 +0000</pubDate>
      <link>https://dev.to/cescquintero/he-estado-haciendo-degoogle-desde-el-ano-pasado-y-esto-es-algo-que-me-hubiera-gustado-saber-4nd5</link>
      <guid>https://dev.to/cescquintero/he-estado-haciendo-degoogle-desde-el-ano-pasado-y-esto-es-algo-que-me-hubiera-gustado-saber-4nd5</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/asjordi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F894629%2F81d7f697-bdb2-4284-9b32-59c97a9d3f55.jpeg" alt="asjordi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/asjordi/configurar-servidor-de-archivos-local-con-ubuntu-y-samba-4o4j" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Configurar servidor de archivos local con Ubuntu y Samba&lt;/h2&gt;
      &lt;h3&gt;Jordi Ayala ・ Jan 13 '25&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#linux&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ubuntu&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#spanish&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>spanish</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>¿Cuál es la diferencia entre :destroy y :delete en Rails?</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Thu, 13 Aug 2020 17:01:50 +0000</pubDate>
      <link>https://dev.to/cescquintero/cual-es-la-diferencia-entre-destroy-y-delete-en-rails-e5d</link>
      <guid>https://dev.to/cescquintero/cual-es-la-diferencia-entre-destroy-y-delete-en-rails-e5d</guid>
      <description>&lt;p&gt;Una de las enseñanzas o instrucciones que se da cuando se diseñan bases de datos es que no debe haber información relacionada que no tenga su “dueño” o “padre”. Si un artículo tiene muchos comentarios y dicho artículo se elimina de la base de datos, tales comentarios también deben hacerlo.&lt;/p&gt;

&lt;p&gt;En SQL a esto se le llama &lt;a href="https://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php" rel="noopener noreferrer"&gt;borrado en cascada&lt;/a&gt;. Para lograr esto en Rails usando ActiveRecord podemos usar la opción &lt;code&gt;dependent&lt;/code&gt; y pasando algunas opciones disponibles.&lt;/p&gt;

&lt;p&gt;A continuación trataré de explicar la diferencia entre las dos más comunes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;:destroy&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Se utiliza así:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:payment_methods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :destroy&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La opción &lt;code&gt;:destroy&lt;/code&gt; le dice a ActiveRecord que elimine los registros hijos pero usando el método &lt;code&gt;destroy&lt;/code&gt; de cada uno de ellos, es decir, primero los instancia y luego los elimina, uno por uno.&lt;/p&gt;

&lt;p&gt;Si hay muchos registros hijos, será muy lento de esta forma.&lt;/p&gt;

&lt;p&gt;Así luce mi consola al usar esta opción:&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;User&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.4&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;"users"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="no"&gt;ORDER&lt;/span&gt; &lt;span class="no"&gt;BY&lt;/span&gt; &lt;span class="s2"&gt;"users"&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;ASC&lt;/span&gt; &lt;span class="no"&gt;LIMIT&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"LIMIT"&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="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="no"&gt;PaymentMethod&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;"payment_methods"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"user_id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"user_id"&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;SQL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;24.7&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&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;SQL&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
  &lt;span class="no"&gt;SQL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&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;SQL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.4&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&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="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;COMMIT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;:delete_all&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Se utiliza así:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:payment_methods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :delete_all&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En cambio, la opción &lt;code&gt;:delete_all&lt;/code&gt; lo que hace es una eliminación directa mediante una consulta SQL pura. Más eficiente si hay muchos registros asociados a un padre.&lt;/p&gt;

&lt;p&gt;Así luce mi consola cuando uso esta opción:&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;User&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.4&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;"users"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="no"&gt;ORDER&lt;/span&gt; &lt;span class="no"&gt;BY&lt;/span&gt; &lt;span class="s2"&gt;"users"&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;ASC&lt;/span&gt; &lt;span class="no"&gt;LIMIT&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"LIMIT"&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="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="no"&gt;SQL&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"payment_methods"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"user_id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"user_id"&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;SQL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&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;DELETE&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&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="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;COMMIT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usar &lt;code&gt;:delete_all&lt;/code&gt; no efectúa el llamado a cualquier callback definido en el modelo.&lt;/p&gt;

&lt;p&gt;Así que hay varios puntos aquí para diferenciar estas dos opciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:destroy:&lt;/code&gt; Instancia cada objeto. Llamado a &lt;em&gt;callbacks&lt;/em&gt;. Menos eficiente.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:delete_all:&lt;/code&gt; Borrado directo por SQL. No llama a &lt;em&gt;callbacks&lt;/em&gt;. Más eficiente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dicha eficiencia depende de lo que se necesite hacer y es un costo aceptable en muchas ocasiones.&lt;/p&gt;

&lt;p&gt;Cualquiera de los dos es correcto usar, ya cada caso particular determina cuál elegir al final.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enlaces
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/association_basics.html#has-many-association-reference" rel="noopener noreferrer"&gt;Documentación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/2797339/rails-dependent-destroy-vs-dependent-delete-all" rel="noopener noreferrer"&gt;Explicado en Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>spanish</category>
    </item>
    <item>
      <title>📖 [ebook] Evaluación de 4 Herramientas de Vídeo Llamadas Web</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Wed, 08 Jul 2020 15:29:02 +0000</pubDate>
      <link>https://dev.to/cescquintero/ebook-evaluacion-de-4-herramientas-de-video-llamadas-web-33gm</link>
      <guid>https://dev.to/cescquintero/ebook-evaluacion-de-4-herramientas-de-video-llamadas-web-33gm</guid>
      <description>&lt;p&gt;Hace ya varios meses que vengo trabajando en un proyecto para crear una aplicación web con la cual poder comunicarse con otras personas desde un navegador web. Sobre ese proyecto &lt;a href="https://otroespacioblog.wordpress.com/2020/06/03/pasen-a-intrati/" rel="noopener noreferrer"&gt;escribí en mí blog personal&lt;/a&gt;. En futuras entradas escribiré acá al respecto.&lt;/p&gt;

&lt;p&gt;En esta oportunidad, vengo a comentar sobre un reporte o evaluación que hice sobre 4 herramientas para comunicarnos y colaborar con amigos o colegas &lt;strong&gt;mediante vídeos llamadas desde un navegador web&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Es gracias a &lt;strong&gt;WebRTC&lt;/strong&gt; que se dan estos servicios. Una tecnología con algunos años encima pero que todavía está en evolución y mejorando cada año.&lt;/p&gt;

&lt;p&gt;Las herramientas o servicios destacadas son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://whereby.com/" rel="noopener noreferrer"&gt;Whereby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.join.me/es" rel="noopener noreferrer"&gt;Joinme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.eyeson.com/" rel="noopener noreferrer"&gt;Eyeson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://team.video/" rel="noopener noreferrer"&gt;Team Video&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todas excelentes opciones que funciona muy bien y tienen una buena variedad de características para trabajar con ellas en equipos pequeños y/o medianos.&lt;/p&gt;

&lt;p&gt;De manera gratuita puedes obtener el reporte en &lt;a href="https://gumroad.com/l/4herramientas" rel="noopener noreferrer"&gt;Gumroad&lt;/a&gt; o &lt;a href="https://leanpub.com/herramientas-video-llamada-web" rel="noopener noreferrer"&gt;Leanpub&lt;/a&gt;. Si lees esto, te animo a leerlo y probar alguna de las herramientas mencionadas.&lt;/p&gt;

</description>
      <category>spanish</category>
    </item>
    <item>
      <title>Got a "TypeError: 'get peerIdentity'" in EmberJS and not in Svelte. Do you know why?</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Thu, 02 Apr 2020 18:55:48 +0000</pubDate>
      <link>https://dev.to/cescquintero/got-a-typeerror-get-peeridentity-in-emberjs-and-not-in-svelte-do-you-know-why-5bk0</link>
      <guid>https://dev.to/cescquintero/got-a-typeerror-get-peeridentity-in-emberjs-and-not-in-svelte-do-you-know-why-5bk0</guid>
      <description>&lt;p&gt;Hi! This is the first time I'm asking a question here at DEV :) Hope you can shed some light on this thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I'm working on a personal project that uses the &lt;a href="https://github.com/twilio/twilio-video.js" rel="noopener noreferrer"&gt;Twilio Video API&lt;/a&gt;. This project was started using &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; and everything was really fine and working.&lt;/p&gt;

&lt;p&gt;However, I had to move the project to another JavaScript framework/library after facing issues related to Webpack and the most up to date Svelte router libraries I could find.&lt;/p&gt;

&lt;p&gt;I decided to move the code to EmberJS. At first, it was going good BUT&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb3vzzt4juwls8zoccw7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb3vzzt4juwls8zoccw7.gif" alt="now what" width="500" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;when I imported the &lt;code&gt;twilio-video&lt;/code&gt; package in a class file, this error appeared in the browser and halted the execution of the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: 'get peerIdentity' called on an object that does not implement interface RTCPeerConnection.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Of course, I &lt;a href="https://github.com/twilio/twilio-video.js/issues/811" rel="noopener noreferrer"&gt;found a related issue&lt;/a&gt; in the library GitHub page and it suggested upgrading to a recent version. I did it but the error didn't go away. I even downgraded the library to the same version I was using in the Svelte project but it kept happening.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/twilio/twilio-video.js/issues/811" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Importing Twilio-Video breaks page in Firefox 70+ with RTC disabled
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#811&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/graue" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars3.githubusercontent.com%2Fu%2F1730853%3Fv%3D4" alt="graue avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/graue" rel="noopener noreferrer"&gt;graue&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/twilio/twilio-video.js/issues/811" rel="noopener noreferrer"&gt;&lt;time&gt;Nov 20, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;ul&gt;
&lt;li&gt;[x] I have verified that the issue occurs with the latest twilio-video.js release and is not marked as a known issue in the &lt;a href="https://github.com/twilio/twilio-video.js/blob/master/CHANGELOG.md" rel="noopener noreferrer"&gt;CHANGELOG.md&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;[x] I reviewed the &lt;a href="https://github.com/twilio/twilio-video.js/blob/master/COMMON_ISSUES.md" rel="noopener noreferrer"&gt;Common Issues&lt;/a&gt; and open GitHub issues and verified that this report represents a potentially new issue.&lt;/li&gt;
&lt;li&gt;[x] I verified that the &lt;a href="https://github.com/twilio/video-quickstart-js" rel="noopener noreferrer"&gt;Quickstart&lt;/a&gt; application works in my environment.&lt;/li&gt;
&lt;li&gt;[x] I am not sharing any &lt;a href="https://www.twilio.com/docs/glossary/what-is-personally-identifiable-information-pii" rel="nofollow noopener noreferrer"&gt;Personally Identifiable Information (PII)&lt;/a&gt;
or sensitive account information (API keys, credentials, etc.) when reporting this issue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Code to reproduce the issue:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight highlight-source-js js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;TwilioVideo&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'twilio-video'&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;...in Firefox 70+ with &lt;code&gt;media.peerconnection.enabled&lt;/code&gt; set to &lt;code&gt;false&lt;/code&gt; in &lt;code&gt;about:config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expected behavior:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Twilio SDK should see that WebRTC is not available and still allow other functions on the page to work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Actual behavior:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Entire page is brought down &lt;em&gt;at import time&lt;/em&gt; by undefined reference to global &lt;code&gt;mozRTCSessionDescription&lt;/code&gt; (&lt;a href="https://github.com/twilio/twilio-webrtc.js/issues/106" rel="noopener noreferrer"&gt;https://github.com/twilio/twilio-webrtc.js/issues/106&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;When I tried patching around this, I hit &lt;a href="https://github.com/twilio/twilio-webrtc.js/blob/7716be1/lib/rtcpeerconnection/firefox.js#L257" rel="noopener noreferrer"&gt;another undefined reference&lt;/a&gt; to &lt;code&gt;RTCPeerConnection&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These references both need to be fixed to ensure importing Twilio-Video, even when WebRTC is disabled, doesn't break non-call related functions on the page. The simplest fix would seem to be accessing both via &lt;code&gt;window&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Software versions:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Browser(s): Firefox 70+&lt;/li&gt;
&lt;li&gt;Operating System: Linux, but likely all&lt;/li&gt;
&lt;li&gt;twilio-video.js: 2.0.0-beta15&lt;/li&gt;
&lt;li&gt;Third-party libraries (e.g., Angular, React, etc.): not relevant&lt;/li&gt;
&lt;/ul&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/twilio/twilio-video.js/issues/811" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Funny Thing is...
&lt;/h2&gt;

&lt;p&gt;Just out of curiosity, I tried the complaining version &lt;code&gt;twilio-video 2.0.0-beta16&lt;/code&gt; in the Svelte project and guess what? It worked!&lt;/p&gt;

&lt;p&gt;With Svelte the error doesn't happen!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj37vafnxufkw90ydjaut.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj37vafnxufkw90ydjaut.gif" alt="wizard" width="480" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But I'm still stucked in the EmberJS app so I need a solution to keep going.&lt;/p&gt;

&lt;p&gt;Fortunately, the Twilio Video library can be used with a CDN and I proceeded to use it that way. The error keeps showing up but it doesn't halt the normal execution of the EmberJS app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;So now I face the question Why does this happen in EmberJS and not in Svelte? To my knowledge, Svelte is kind of a compiler and that could be related.&lt;/p&gt;

&lt;p&gt;Is there a way to keep using the NPM version of the library in a way that the error doesn't break the app?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>help</category>
    </item>
    <item>
      <title>Cómo Encontrar Archivos por Tamaño Usando la Consola</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Mon, 25 Nov 2019 21:18:26 +0000</pubDate>
      <link>https://dev.to/cescquintero/como-encontrar-archivos-por-tamano-usando-la-consola-20ea</link>
      <guid>https://dev.to/cescquintero/como-encontrar-archivos-por-tamano-usando-la-consola-20ea</guid>
      <description>&lt;p&gt;A veces hay tantas cosas que hacer que algunas tareas básicas o sencillas se nos olvidan. Solemos darle más importancia a unas cosas por encima de otras por su peso o prioridad, sin embargo, hay tareas menores que permiten que esas grandes puedan ser resultas sin complicaciones.&lt;/p&gt;

&lt;p&gt;Con lo anterior me refiero al mantenimiento que generalmente hay que hacerle a nuestros equipos electrónicos, electrodomésticos y más aparatos que usamos en el día a día. Así como a un vehículo hay que llevarlo a revisión cada tantos kilómetros, también debemos revisar nuestros equipos(computadores, celulares, tabletas, etc) cada tanto.&lt;/p&gt;

&lt;p&gt;Una tarea sencilla de mantenimiento es hacer espacio en disco duro. Puede que parezca que influya pero un disco duro con muchos archivos tiene que moverse mucho para leer y acceder a la información. No por nada se habla de &lt;strong&gt;fragmentación de disco&lt;/strong&gt;. Considero importante mantener el disco duro libre de archivos innecesarios o prescindibles.&lt;/p&gt;

&lt;p&gt;En Windows, herramientas como &lt;em&gt;CCleaner&lt;/em&gt; ayudan con esta labor. Hacen un escaneo del sistema y &lt;a href="https://otroespacioblog.wordpress.com/2012/08/11/ver-archivos-ocultos/" rel="noopener noreferrer"&gt;encuentran archivos&lt;/a&gt; viejos, con cero uso o con reglas en particular e indican que se pueden borrar sin llegar a afectar el funcionamiento del sistema.&lt;/p&gt;

&lt;p&gt;En Linux podemos lograr algo similar usando el comando &lt;code&gt;find&lt;/code&gt;. &lt;a href="https://otroespacioblog.wordpress.com/2017/01/11/busca-y-encuentra-en-linux-con-el-comando-find/" rel="noopener noreferrer"&gt;Este comando es bien avanzado&lt;/a&gt; y al día de hoy no logro recordar su sintaxis al usarlo, no obstante, hoy dejaré aquí una forma en la que este ayuda a encontrar archivos que cumplan unas reglas según su tamaño y así saber qué borrar o qué ocupa mucho espacio en nuestro disco duro.&lt;/p&gt;

&lt;p&gt;La sintaxis del comando para esta tarea es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find CARPETA &lt;span class="nt"&gt;-size&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;+ | -]TAMAÑO-ARCHIVO[M | G] &lt;span class="nt"&gt;-ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;find&lt;/code&gt;: es el comando&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CARPETA&lt;/code&gt;: es el nombre o ruta de la carpeta que queremos analizar&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-size&lt;/code&gt;: parámetro para encontrar archivos por su tamaño&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[+ | -]&lt;/code&gt;: indicativo de si queremos encontrar archivos mayores a o menores al tamaño indicado&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TAMAÑO-ARCHIVO&lt;/code&gt;: número que indica el peso buscado, ejemplo 10 o 50&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[M | G]&lt;/code&gt;: peso del archivo sea en mega bytes o giga bytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-ls&lt;/code&gt;: opción que ejecuta un listado de archivos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Entonces si queremos aplicarlo para encontrar los archivos que pesen más de 10 mega bytes en la carpeta &lt;code&gt;~/.local/share/Steam&lt;/code&gt; sería algo así:&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;find ~/.local/share/Steam &lt;span class="nt"&gt;-size&lt;/span&gt; +10M &lt;span class="nt"&gt;-ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que retorna:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;654973 101896 -rw-r--r-- 1 cesc cesc 104339036 Feb 18 2017 /home/cesc/.local/share/Steam/ubuntu12_32/steam-runtime.tar.xz
9312085 14468 -rw-r--r-- 1 cesc cesc 14812720 Sep 6 2016 /home/cesc/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libCg.so
8918774 51200 -rwxr-xr-x 1 cesc cesc 52428800 Dec 5 2016 /home/cesc/.local/share/Steam/ubuntu12_32/steam-runtime.tar.xz.part0
8918678 20036 -rwxr-xr-x 1 cesc cesc 20516356 Jan 18 2017 /home/cesc/.local/share/Steam/ubuntu12_32/steamui.so
8918683 10896 -rwxr-xr-x 1 cesc cesc 11156651 Aug 9 2016 /home/cesc/.local/share/Steam/ubuntu12_32/libv8.so
8918676 19480 -rwxr-xr-x 1 cesc cesc 19946042 Jan 18 2017 /home/cesc/.local/share/Steam/ubuntu12_32/steamclient.so
8918775 50696 -rwxr-xr-x 1 cesc cesc 51910236 Dec 5 2016 /home/cesc/.local/share/Steam/ubuntu12_32/steam-runtime.tar.xz.part1
8918682 11952 -rwxr-xr-x 1 cesc cesc 12237291 Aug 9 2016 /home/cesc/.local/share/Steam/ubuntu12_32/libicuuc.so
8918688 19428 -rwxr-xr-x 1 cesc cesc 19890531 Jan 18 2017 /home/cesc/.local/share/Steam/linux64/steamclient.so
8918687 18968 -rwxr-xr-x 1 cesc cesc 19422864 Jan 18 2017 /home/cesc/.local/share/Steam/linux32/steamclient.so
8654997 15852 -rw-r--r-- 1 cesc cesc 16231428 Feb 18 2017 /home/cesc/.local/share/Steam/package/bins_ubuntu12.zip.vz.820d6d40f511509f17d4681722fd8026da2b38ba_16231428
8654985 11796 -rw-r--r-- 1 cesc cesc 12077027 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_fonts_all.zip.vz.7673e4cd32b6752bc621d8bc1a7118a9af19b64a_12077027
8655003 28708 -rw-r--r-- 1 cesc cesc 29396785 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_images_all.zip.vz.1ea174b9274bc15e751452adabc94a6715ed70a0_29396785
8655004 51212 -rw-r--r-- 1 cesc cesc 52440846 Feb 18 2017 /home/cesc/.local/share/Steam/package/runtime_part0_ubuntu12.zip.7cb113a5d6be4486ecd4873ea6460a30f8050ae8
8655006 50708 -rw-r--r-- 1 cesc cesc 51922032 Feb 18 2017 /home/cesc/.local/share/Steam/package/runtime_part1_ubuntu12.zip.f6f98a289f5af2c121b04cb9ede621b16f4c8dd0
8655005 42148 -rw-r--r-- 1 cesc cesc 43156347 Feb 18 2017 /home/cesc/.local/share/Steam/package/webkit_ubuntu12.zip.vz.ea5e4def93c6c6adde86a3d7f799f033c1aadbf3_43156347
8654986 12872 -rw-r--r-- 1 cesc cesc 13179376 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_misc_all.zip.008ed314d467eecacba58d188fdf082d23f264d2
8654988 11988 -rw-r--r-- 1 cesc cesc 12274769 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_dicts_all.zip.87bb49891925214df2d745e12a53518fd2ea86f0
8657434 111640 -rwxr-xr-x 1 cesc cesc 114312140 Jan 4 2017 /home/cesc/.local/share/Steam/ubuntu12_64/libcef.so
8655486 16044 -rwxr-xr-x 1 cesc cesc 16426032 May 12 2015 /home/cesc/.local/share/Steam/tenfoot/resource/fonts/NotoSansCJKjp-Regular.otf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se puede combinar para encontrar archivos dentro de un rango usando una combinación de signo positivo y negativo al lado del tamaño del archivo. Ejemplo:&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;find ~/.local/share/Steam &lt;span class="nt"&gt;-size&lt;/span&gt; +10M &lt;span class="nt"&gt;-size&lt;/span&gt; &lt;span class="nt"&gt;-15M&lt;/span&gt; &lt;span class="nt"&gt;-ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8918683 10896 -rwxr-xr-x 1 cesc cesc 11156651 Aug 9 2016 /home/cesc/.local/share/Steam/ubuntu12_32/libv8.so
8918682 11952 -rwxr-xr-x 1 cesc cesc 12237291 Aug 9 2016 /home/cesc/.local/share/Steam/ubuntu12_32/libicuuc.so
8654985 11796 -rw-r--r-- 1 cesc cesc 12077027 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_fonts_all.zip.vz.7673e4cd32b6752bc621d8bc1a7118a9af19b64a_12077027
8654986 12872 -rw-r--r-- 1 cesc cesc 13179376 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_misc_all.zip.008ed314d467eecacba58d188fdf082d23f264d2
8654988 11988 -rw-r--r-- 1 cesc cesc 12274769 Feb 18 2017 /home/cesc/.local/share/Steam/package/tenfoot_dicts_all.zip.87bb49891925214df2d745e12a53518fd2ea86f0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;De esa forma se pueden encontrar archivos pesados en el disco duro. Y de esa forma me di cuenta que hay archivos por borrar de Steam, aplicación que ya había desinstalado pero parece que dejó archivos de configuración por ahí.&lt;/p&gt;

&lt;p&gt;Como casi siempre &lt;a href="https://askubuntu.com/questions/36111/whats-a-command-line-way-to-find-large-files-directories-to-remove-and-free-up/36114#36114" rel="noopener noreferrer"&gt;la solución a esta situación&lt;/a&gt; la encontré en Ask Ubuntu(comunidad de Stack Exchange).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Este artículo fue publicado &lt;a href="https://otroespacioblog.wordpress.com/2018/02/03/como-encontrar-archivos-por-tamano-usando-la-consola/" rel="noopener noreferrer"&gt;primero en mi blog personal&lt;/a&gt;, Otro Espacio Blog. Ahí escribo sobre todo lo que aprendo al programar y también sobre temas no relacionados a tecnología.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ubuntu</category>
      <category>spanish</category>
    </item>
    <item>
      <title>¿Puede ActiveRecord::Relation recibir mensajes de métodos de clase? Sí, sí puede</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Fri, 22 Nov 2019 15:52:48 +0000</pubDate>
      <link>https://dev.to/cescquintero/puede-activerecord-relation-recibir-mensajes-de-metodos-de-clase-si-25dn</link>
      <guid>https://dev.to/cescquintero/puede-activerecord-relation-recibir-mensajes-de-metodos-de-clase-si-25dn</guid>
      <description>&lt;p&gt;Ruby on Rails es una criatura enorme. Ofrece muchas funcionalidades y elementos que hacen fácil la vida de quien usa el &lt;em&gt;framework&lt;/em&gt; bajo el nombre de magia. Magia que muchas veces no tenemos ni idea de cómo funciona.&lt;/p&gt;

&lt;p&gt;Algunos podrán decir que esa magia es muy mala al ocultar cosas a quien desarrolla. Otros dirán que es buena justamente por lo mismo. En todo caso, siempre está la posibilidad de examinar el código fuente y ver cómo toda esa magia trabaja bajo cuerda.&lt;/p&gt;

&lt;p&gt;Hace algunos días me topé con una de esas magias que sin querer sabía cómo funcionaba pero no había analizado tanto.&lt;/p&gt;

&lt;h2&gt;
  
  
   Métodos de Clase y Scopes
&lt;/h2&gt;

&lt;p&gt;Los &lt;code&gt;scopes&lt;/code&gt; en Rails son una buena forma de crear métodos para hacer consultas sin necesidad de definir un método de clase. Su sintaxis es más sencilla y en muchas ocasiones corta.&lt;/p&gt;

&lt;p&gt;Uno de los beneficios explícitos de usarlos es poder encadenarlos para hacer una cadena de invocación:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Algo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:available&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;available: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los &lt;em&gt;scopes&lt;/em&gt; &lt;code&gt;default&lt;/code&gt; y &lt;code&gt;available&lt;/code&gt; pueden encadenarse uno tras otro:&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;Algo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;available&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con métodos de clase no es esto posible.&lt;/p&gt;

&lt;h2&gt;
  
  
   Entra &lt;code&gt;ActiveRecord::Relation&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Bueno, resulta que en un proyecto en el que trabajo estaba este método de clase que parecía no tener uso.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Taker&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;
    &lt;span class="c1"&gt;# implementación&lt;/span&gt;
  &lt;span class="k"&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;Cuando en Sublime Text o Atom se hacía una búsqueda de &lt;code&gt;Taker.to_csv&lt;/code&gt; no aparecía nada. Pensé que nada lo usaba. Permití que se borrara su test y esa implementación en el modelo.&lt;/p&gt;

&lt;p&gt;Al par de días, un error aparece. ¿Qué será? Inicia el nuevo &lt;em&gt;sprint&lt;/em&gt;, me asignan dicho bug y procedo a revisar qué ocurre. Como le habíamos hecho refactor a ese modelo, pensé que algo podría haberse movido a donde no correspondía así que empecé por lo obvio, comparar lo actual con un &lt;em&gt;commit&lt;/em&gt; viejo pero no, no era por ahí.&lt;/p&gt;

&lt;p&gt;Luego de analizar por un momento la situación, pensé en traer de nuevo ese viejo método borrado y probar. Y esa era la solución. Por alguna razón, ese método de clase era lo que faltaba.&lt;/p&gt;

&lt;p&gt;Pero, ¿por qué un método de clase podría llamarse en una colección? Resulta que lo que llamaba al método era el resultado de una consulta con un &lt;code&gt;#where&lt;/code&gt;. Uno creería que para usar métodos de clase habría que siempre usar el nombre de la clase y pasar el mensaje, es decir, el método. Resulta que no. Esa magia "oculta" de Rails lo hace posible.&lt;/p&gt;

&lt;p&gt;La explicación está dada en &lt;a href="https://stackoverflow.com/a/21681483/1407371" rel="noopener noreferrer"&gt;Stack Overflow&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;By definition, model scopes return &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; objects&lt;/li&gt;
&lt;li&gt;By definition, scopes have access to class methods&lt;/li&gt;
&lt;li&gt;Therefore, &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; objects have access to class methods&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Español:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Por definición, los scopes retornan instancias de &lt;code&gt;ActiveRecord::Relation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Por definición, los scopes tienen acceso a los métodos de clase&lt;/li&gt;
&lt;li&gt;Por lo tanto, instancias &lt;code&gt;ActiveRecord::Relation&lt;/code&gt; tienen acceso a métodos de clase&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ta da! Estuvo siempre sobre mis narices solo que no eran tan obvio.&lt;/p&gt;

&lt;p&gt;El código culpable tenía la línea:&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="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filtered_ts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En primera medida creíamos que ese &lt;code&gt;.to_csv&lt;/code&gt; era algún método de Rails como tal y no el que estaba definido en el modelo. Cuando aparece el bug comprobamos que no era así y está dado por la explicación anterior.&lt;/p&gt;

&lt;p&gt;Esta situación nos tomó por sorpresa. El bug no fue algo mayor y tuvimos la fortuna de aprender algo más de la mucha magia que hay en el &lt;em&gt;framework&lt;/em&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Este artículo fue publicado &lt;a href="https://otroespacioblog.wordpress.com/2018/01/25/puede-activerecordrelation-recibir-mensajes-de-metodos-de-clase-si/" rel="noopener noreferrer"&gt;primero en mi blog personal&lt;/a&gt;, Otro Espacio Blog. Ahí escribo sobre todo lo que aprendo al programar y también sobre temas no relacionados a tecnología.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webdev</category>
      <category>spanish</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Servidores: ¿Mascotas o Ganado?</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Wed, 20 Nov 2019 15:31:07 +0000</pubDate>
      <link>https://dev.to/cescquintero/servidores-mascotas-o-ganado-49gk</link>
      <guid>https://dev.to/cescquintero/servidores-mascotas-o-ganado-49gk</guid>
      <description>&lt;p&gt;Recuerdo, hace ya varios años, en una empresa pequeña en la cual trabajé un día mi jefe me encargó una tarea que me hizo coger gusto e interés en el mundo de operaciones o lo que suelen llamar DevOps.&lt;/p&gt;

&lt;p&gt;Se me acerca un día miércoles o jueves y me dice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Frank, el servidor dedicado nos cuesta X cantidad de dólares. Si el sábado logras migrar todos los sitios web que están ahí hospedados a servidores en Linode, te doy esa X cantidad a ti. Sino, toca pagar y en todo caso debes hacer la migración.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09sozkvdeh7i9i1f5ziq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09sozkvdeh7i9i1f5ziq.png" alt="saitama ok" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ya venía trabajando algún tiempo con &lt;a href="https://www.linode.com/docs/websites/hosting-a-website-ubuntu-18-04/" rel="noopener noreferrer"&gt;configuraciones en Linode&lt;/a&gt; por lo cual no había tanto desconocido pero la tarea pedía completarse en tiempo casi récord. Bueno, al final de la historia lo logré pero el resultado fue 20, aprox, servidores(más direcciones IP, más DNS, etc) que debía gestionar a diario.&lt;/p&gt;

&lt;p&gt;Cuando algo ocurría en alguno de esos 20 servidores tenía que buscar la mejor solución sin dañar la máquina y así evitar la caída del sitio web alojado. Bastante tedioso el tema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mascota o Ganado, ¿qué prefieres?
&lt;/h2&gt;

&lt;p&gt;Adelanto algunos años y en otra empresa en qué trabajé debí diseñar e implementar la arquitectura para una SaaS. En el diseño se contemplaba usar un balanceador de carga y diferentes máquinas detrás de este. Estuvo muy claro que debía valerme de las populares AMI de AWS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Una AMI es una &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html" rel="noopener noreferrer"&gt;Amazon Machine Image&lt;/a&gt; que viene siendo una copia de un servidor lista para lanzarse como uno con la menor cantidad de configuración posible. Muy similar como en &lt;a href="https://docs.oracle.com/cd/E26217_01/E26796/html/qs-import-vm.html" rel="noopener noreferrer"&gt;VirtualBox las OVA u OVF&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Entonces ocurría que tenía una AMI para el(los) servidor(es) que alojarían la API y los procesos en segundo plano, otra AMI para el cliente web(una &lt;a href="https://otroespacioblog.wordpress.com/2015/03/21/javascript-frameworks-a-la-orden-del-dia/" rel="noopener noreferrer"&gt;app Angular&lt;/a&gt;) y otra AMI para el &lt;a href="https://otroespacioblog.wordpress.com/2016/11/17/integracion-continua-entrega-continua-y-despliegue-continuo-que-cuando-y-como/" rel="noopener noreferrer"&gt;servidor de integración continua&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cuándo había problemas en cualquiera de ellos, ingresaba en el servidor en cuestión, buscando de la lista de IPs donde cada máquina tenía un número y un comando al lado para ingresa prontamente. Si en algún momento el problema era complicado, simplemente optaba por “matar” la máquina y recrear una nueva a partir de la AMI.&lt;/p&gt;

&lt;p&gt;Es así que por un lado está la experiencia de tener que cuidar a las máquinas con cariño y esmero; y en el otro lado estaban las máquinas “desechables”. Luego aprendí que hay un nombre, no estándar, pero sí muy preciso a modo de analogía, para determinar cómo se está administrando la infraestructura de un producto web: si &lt;a href="https://www.engineyard.com/blog/pets-vs-cattle" rel="noopener noreferrer"&gt;como mascota o como ganado&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Infraestructura como mascota o ganado(&lt;em&gt;pet vs cattle&lt;/em&gt;) significa que si tenemos un servidor que cuidamos mucho y que en caso de fallo el servicio se interrumpe, &lt;strong&gt;estamos hablando de un servidor tipo mascota&lt;/strong&gt;. Como un perrito el cual cuidas, alimentas, mimas, etc.&lt;/p&gt;

&lt;p&gt;Por otro lado, si el servidor simplemente, al menor indicio de un problema de muchas horas y esfuerzo, puede ser fácilmente eliminado y reproducido, sin causar mayor inconveniente a la operación del producto, &lt;strong&gt;estamos hablando de un servidor tipo ganado&lt;/strong&gt;. Como las vacas, la ordeñas, le sacas cría, luego le sacas todo su producto(carne, cuero, hueso, etc) y vuelves a criar la cría para que un día repita el ciclo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtscsj8yfqpf9ph2ebqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtscsj8yfqpf9ph2ebqq.png" alt="aws cloud design with cloudcraft" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Da la sensación que hoy en día lo ideal sería tener todo como ganado. Si tenemos en cuenta la popularidad de plataformas en la nube como AWS, Google Cloud, Microsoft Azure y otras un poco menos grandes como Digital Ocean, Linode o &lt;a href="https://otroespacioblog.wordpress.com/2017/12/14/clouding-una-nueva-alternativa-en-infraestructura-web/" rel="noopener noreferrer"&gt;Clouding&lt;/a&gt;, pensar en gestionar los servidores como mascota debería ser impensable. Sin embargo, cada uno tiene su caso de uso.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS, Docker, Packer, Cloud init
&lt;/h2&gt;

&lt;p&gt;Es válido optar por una mentalidad donde &lt;strong&gt;la infraestructura web sea fácilmente reemplazable&lt;/strong&gt;, donde las configuraciones se hagan una sola vez y sea más sencillo replicar que corregir, donde descartar sea mejor que indagar y resolver(no siempre, pero en algunos casos sí), no obstante, hay situaciones donde vamos a tener un servidor que cuidemos y demos todo el cariño del caso, y no quiere decir que esté mal.&lt;/p&gt;

&lt;p&gt;En los casos en los que se quiera tener configuraciones repetibles uno se puede valor de herramientas como las AWS AMI(se pueden crear en la consola de AWS o usando &lt;a href="https://www.packer.io/" rel="noopener noreferrer"&gt;Packer&lt;/a&gt;), imágenes en Docker, o scripts escritos en Bash que se ejecuten por medio de &lt;a href="https://www.cloudsigma.com/es/introduccion-al-aprovisionamiento-de-servidores-de-nube-con-cloudinit/" rel="noopener noreferrer"&gt;cloud-init&lt;/a&gt;. Cada una tiene su forma de trabajo diferente pero generalmente apuntan al mismo objetivo: hacer y deshacer como pan de cada día servidores.&lt;/p&gt;

&lt;p&gt;Ahora, en el caso cuando debemos mantener con cuidado y por mucho tiempo a una misma máquina(o varias), lo ideal es aceptar esta situación y pensar siempre en cuadrar todo de una forma en que &lt;strong&gt;haya rutas definidas para identificar errores y poder resolver situaciones que interrumpan el normal funcionamiento lo más pronto posible&lt;/strong&gt;. Con esto me refiero a herramientas de monitoreo, centralización de logs, generación de logs de comandos y/o procesos personalizados, procesos siempre vigilados por un supervisor de procesos(systemd, upstart, pm2, &lt;a href="https://github.com/ddollar/foreman/" rel="noopener noreferrer"&gt;foreman&lt;/a&gt;, &lt;a href="https://mmonit.com/monit/" rel="noopener noreferrer"&gt;monit&lt;/a&gt;, &lt;a href="http://godrb.com/" rel="noopener noreferrer"&gt;god&lt;/a&gt;), mantenimientos programados y como no, respaldos(backups) de todo.&lt;/p&gt;

&lt;p&gt;Finalmente, &lt;strong&gt;no se puede decir que haya un acercamiento mejor o peor&lt;/strong&gt;, todo depende del caso de uso, del manejo que se requiera y sea adecuado según el proyecto, plataforma o necesidad.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Este artículo fue publicado &lt;a href="https://otroespacioblog.wordpress.com/2018/08/07/servidores-mascotas-o-ganado/" rel="noopener noreferrer"&gt;primero en mi blog personal&lt;/a&gt;, Otro Espacio Blog. Ahí escribo sobre todo lo que aprendo al programar y también sobre temas no relacionados a tecnología.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JavaScript y el DOM: keyDown vs keyPress</title>
      <dc:creator>Francisco Quintero 🇨🇴</dc:creator>
      <pubDate>Tue, 19 Nov 2019 19:03:44 +0000</pubDate>
      <link>https://dev.to/cescquintero/javascript-y-el-dom-keydown-vs-keypress-16af</link>
      <guid>https://dev.to/cescquintero/javascript-y-el-dom-keydown-vs-keypress-16af</guid>
      <description>&lt;p&gt;Formularios. Qué sería de nuestro software web sin formularios. La majestuosa forma de permitir a los usuarios de un sistema ingresar información.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;En realidad los formularios son un dolor de cabeza&lt;/strong&gt;. Entre menos campos tengan mejor pero hay situaciones donde el mínimo de campos es muchos campos. Un ejemplo de eso es aplicaciones del sector salud donde hay que tomar muchos datos de un paciente.&lt;/p&gt;

&lt;p&gt;Para disminuir el impacto de digitar un formulario tan extenso se busca ayuda de expertos en UX y aún así, por debajo de cuerda, hay muchos campos en un solo formulario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solo ingresar números
&lt;/h2&gt;

&lt;p&gt;Un caso común de formularios es que determinados campos solo permitan ingresar valores numéricos y no letras del alfabeto. En primera instancia se pensaría que el campo tipo número que trajo consigo HTML5 bastaría, pero no.&lt;/p&gt;

&lt;p&gt;Dicho tipo de campo permite que se escriban letras. Su funcionalidad es más orientada al mundo móvil donde en un celular, un campo de tipo número, abre el teclado numérico y no el alfanumérico.&lt;/p&gt;

&lt;p&gt;También está el atributo &lt;code&gt;pattern&lt;/code&gt; para indicar una expresión regular, sin embargo, hasta donde recuerdo(no lo he vuelto a probar) esta solución se queda corta.&lt;/p&gt;

&lt;p&gt;Finalmente, las soluciones más óptimas están dadas por controlar que se ingresa en el campo(s) y prevenir que se ingrese usando un &lt;code&gt;event listener&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aquí es donde el asunto se pone interesante.&lt;/p&gt;

&lt;h2&gt;
  
  
  keyDown, keyUp, keyPress
&lt;/h2&gt;

&lt;p&gt;Los anteriores son eventos que se disparan cuando pasa algo en el teclado del usuario. Estos mismos sirven cuando se quiere prevenir que se ingrese texto en el campo del formulario.&lt;/p&gt;

&lt;p&gt;Hace un par de años implementé una solución de este tipo usando &lt;a href="https://otroespacioblog.wordpress.com/2018/09/01/cosas-de-javascript-seleccionando-id-numerico-con-queryselector/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; y capturando el evento &lt;code&gt;keydown&lt;/code&gt; y evitando que se ingresara texto sino era número o alguna de las teclas especiales como &lt;em&gt;CTRL&lt;/em&gt; o &lt;em&gt;SHIFT&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;La semana pasada, en un proyecto más recién, me tocó implementar algo similar. Lo que hice fue buscar la implementación en el proyecto viejo, sin embargo solo me fijé en la parte interna del manejador de eventos y no en el evento que estaba capturando. En esta nueva implementación usé &lt;code&gt;keypress&lt;/code&gt; y ahí vino una complicación.&lt;/p&gt;

&lt;p&gt;Pasa que &lt;code&gt;keydown&lt;/code&gt; y &lt;code&gt;keypress&lt;/code&gt; varian en un atributo.&lt;/p&gt;

&lt;p&gt;Cada tecla tiene un código único que la diferencia de las demás. En el caso de &lt;code&gt;keypress&lt;/code&gt; este valor viene el atributo &lt;code&gt;charCode&lt;/code&gt; y en &lt;code&gt;keydown&lt;/code&gt; viene en &lt;code&gt;keyCode&lt;/code&gt;. Y resulta que no todas las teclas devuelven un valor para &lt;code&gt;charCode&lt;/code&gt; y la implementación fallaba.&lt;/p&gt;

&lt;p&gt;Cuando &lt;a href="https://stackoverflow.com/a/4285697/1407371" rel="noopener noreferrer"&gt;analicé, busqué y probé&lt;/a&gt;, me di cuenta la diferencia entre los dos tipos de evento. En la primera implementación estaba usando &lt;code&gt;keydown&lt;/code&gt; y en la más reciente &lt;code&gt;keypress&lt;/code&gt;. Cuando cambié, todo funcionó como se esperaba.&lt;/p&gt;

&lt;h2&gt;
  
  
   Y entonces, ¿qué uso?
&lt;/h2&gt;

&lt;p&gt;Hoy en día, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Events/keypress" rel="noopener noreferrer"&gt;el uso de &lt;code&gt;keypress&lt;/code&gt; es desaconsejado por MDN ya que está depreciado&lt;/a&gt; y debería cambiarse &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Events/keydown" rel="noopener noreferrer"&gt;por &lt;code&gt;keydown&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Track
&lt;/h2&gt;

&lt;p&gt;Resulta que mientras redactaba este artículo y leía la documentación de los dos eventos, encontré una forma aún más sencilla de impedir el ingreso de texto en campos dispuestos para solo números. Es así según MDN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;numbersOnly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCode&lt;/span&gt;&lt;span class="p"&gt;));&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;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onkeypress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbersOnly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bastante sencilla si se compara con mi implementación la cual usa jQuery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.only-numbers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;46&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;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;65&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;39&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;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shiftKey&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;57&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&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;Vaya diferencia para lograr lo mismo 😀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Este artículo fue &lt;a href="https://otroespacioblog.wordpress.com/2019/02/13/javascript-y-el-dom-keydown-vs-keypress/" rel="noopener noreferrer"&gt;publicado primero en mi blog personal&lt;/a&gt;, Otro Espacio Blog. Ahí escribo sobre todo lo que aprendo al programar y también sobre temas no relacionados a tecnología.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
