Skip to content

Cómo Implementar una Barra de Cookies en Ruby on Rails

ALT

David Morales

Cookies
Photo por Markus Winkler en Unsplash

Vender un servicio o productos online en la Unión Europea te obliga a cumplir con la ley europea de cookies. Consiste en mostrar un mensaje al usuario para que sepa que la web usa cookies para hacerle un seguimiento. Porque seamos honestos, ¿hay alguna tienda online que no monitoree a los usuarios? Las analíticas son cruciales para ver qué producto o página es la más vista, o cuándo y de dónde vienen las visitas.

La Unión Europea piensa que esto violaría la privacidad del usuario, así que las páginas que hagan esto deberían avisar claramente al usuario. Y la solución más popular es mostrar una barra en la parte inferior o superior de la página.

Hasta que no tengas el consentimiento del usuario, no puedes guardar cookies en el navegador. Por tanto, si el usuario no acepta, la visita no contará. Esto es altamente problemático para la mayoría de las webs, así que muchas no siguen esta regla y solo se limitan a mostrar el mensaje.

Voy a mostrarte cómo implementar un ejemplo muy sencillo, usando Ruby on Rails, de una barra de cookies que solo instala la cookie de Google Analytics si el usuario da su consentimiento clicando el botón OK.

¿Quieres ver este artículo en formato video?

Aplicación Rails de ejemplo

Vamos a crear una nueva aplicación de Ruby on Rails paso a paso.

rails new eu-cookie-sampleCode language: Shell Session (shell)

Añade la gema faker a tu Gemfile:

gem 'faker'Code language: Ruby (ruby)

Y reconstruye las dependencias de Bundler:

cd eu-cookie-sample/
bundle installCode language: Shell Session (shell)

Ahora crea un controlador Home con una plantilla index:

rails generate controller Home indexCode language: Shell Session (shell)

Esto también creará una ruta nueva automáticamente. Sustitúyela con una ruta root:

# config/routes.rb

root 'home#index'Code language: Ruby (ruby)

El paso final para tener tu aplicación de ejemplo lista es mostrar algo de contenido aleatorio. Elimina todo el contenido por defecto en app/views/home/index.html.erb y añade esto:

<% Faker::Lorem.paragraphs(number: 40).each do |paragraph| %>
  <p><%= paragraph %></p>
<% end %>Code language: ERB (Embedded Ruby) (erb)

Inicia el servidor de Rails:

rails sCode language: Shell Session (shell)

Y carga localhost:3000 en tu navegador.

Tu aplicación de ejemplo ahora muestra una página lo bastante larga para hacer scroll.

Cargando la librería de cookies

Para manejar las cookies en el navegador del usuario, necesitarás usar la librería de JavaScript js-cookie. La puedes encontrar aquí: https://github.com/js-cookie/js-cookie

Usaremos su versión en CDN para cargarla. Añade esto antes de la etiqueta de cierre del head en app/views/layouts/application.html.erb:

<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>Code language: HTML, XML (xml)

Construyendo la barra con el mensaje

Crea un partial para construir la barra con el mensaje en app/views/layouts/_cookies_bar.html.erb:

<div id="cookies-bar" class="cookies-bar">
  <p>
    Usamos cookies. ¿Las aceptas?
  </p>

  <%= link_to 'Aceptar', request.original_url, class: 'btn accept' %>
  <%= link_to 'Rechazar', request.original_url, class: 'btn reject' %>
</div>Code language: ERB (Embedded Ruby) (erb)

Para simplificar, he puesto un texto muy sencillo en la barra, pero en la realidad sería necesario añadir un enlace apuntando a algún texto legal e instrucciones para eliminar las cookies.

Ahora incluye el partial en el layout de la aplicación, que puedes encontrar en app/views/layouts/application.html.erb, justo debajo de la llamada a yield:

<% if cookies[:allow_cookies].blank? %>
  <%= render 'layouts/cookies_bar' %>
<% end %>Code language: ERB (Embedded Ruby) (erb)

Lo que se está comprobando es si la cookie llamada allow_cookies está definida. Si no lo está, se muestra la barra.

Alternativamente, podrías mostrar también este partial solo para el entorno de producción de esta manera:

<% if !cookies[:allow_cookies] && Rails.env.production? %>Code language: ERB (Embedded Ruby) (erb)

¡Genial! Refresca, y podrás ver la barra en la parte inferior de la página. Pero no está fija y se ve mal. Vamos a aplicar algunos estilos.

Aplicando estilos a la barra

Renombra app/assets/stylesheets/home.scss a main.scss y pega este código SCSS:

body {
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

.cookies-bar {
  position: sticky;
  bottom: 0;

  padding: 0px 10px 5px 10px;

  border: 1px solid #9CA3AF;
  border-bottom: none;
  background-color: #F3F4F6;

  .btn {
    display: block;
    border: 1px solid #4B5563;
    background-color: #6B7280;
    color: #FFF;
    padding: 5px;
    margin-bottom: 5px;
    text-align: center;
    text-decoration: none;

    &.accept:hover {
      background-color: #047857;
    }
    &.reject:hover {
      background-color: #B91C1C;
    }
  }

  @media (min-width: 768px) {
    display: flex;
    max-width: 700px;
    align-items: center;
    margin: 0 auto;
    padding-bottom: 0;

    .btn {
      padding: 10px 20px;
      margin-left: 10px;
    }
  }
}Code language: SCSS (scss)

Así se ve la barra en móvil:

Barra de cookies en móvil

Y esta es la versión de escritorio:

Barra de cookies en escritorio

El código JavaScript

Crea el archivo app/javascript/custom/main.js (crea el directorio custom también) y pega esto:

class CookieBar {
  constructor() {
    this.cookiesBar = document.getElementById('cookies-bar');
  }

  init() {
    if (this.cookiesAllowed()) {
      this.appendGACode();
    }

    this.addButtonBehaviors();
  }

  cookiesAllowed() {
    return Cookies.get('allow_cookies') === 'yes';
  }

  addButtonBehaviors() {
    if (!this.cookiesBar) {
      return;
    }

    this.cookiesBar.querySelector('.accept').addEventListener('click', () => this.allowCookies(true));

    this.cookiesBar.querySelector('.reject').addEventListener('click', () => this.allowCookies(false));
  }

  appendGACode() {
    const ga = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){" +
      "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o)," +
      "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)" +
      "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');" +
      "ga('create', 'UA-XXXXX-Y', 'auto');" + "ga('send', 'pageview');";

    document.getElementsByTagName('head')[0].append('<script>' + ga + '</script>');
  }

  allowCookies(allow) {
    if (allow) {
      Cookies.set('allow_cookies', 'yes', {
        expires: 365
      });

      this.appendGACode();
    } else {
      Cookies.set('allow_cookies', 'no', {
        expires: 365
      });
    }

    this.cookiesBar.classList.add('hidden');
  }
}

window.onload = function() {
  const cookieBar = new CookieBar();

  cookieBar.init();
}
Code language: JavaScript (javascript)

Este código tiene dos partes: la clase y el evento onload.

Si miras el evento onload, verás que se crea la clase y luego se llama al método init. Vamos a desgranar el flujo de estas operaciones:

El archivo que acabas de crear tiene que ser cargado por Rails. Esto se hace modificando el archivo application.js dentro del subdirectorio packs.

Añade este require después del último import:

require("custom/main")Code language: Ruby (ruby)

Ahora… ¡pruébalo!

Si usas Chrome u otro navegador basado en Chromium, abre las herramientas para desarrolladores y abre la pestaña Aplicación. Allí busca Cookies en la barra lateral y expándela para hacer clic en la URL que aparece. Podrás ver la cookie, su valor, y podrás eliminarla.

He subido la aplicación de ejemplo a GitHub: https://github.com/davidmles/eu-cookie-sample

Conclusión

No es tan difícil implementar tu propia solución para seguir la ley europea de cookies. De esta manera, la controlarás mejor en lugar de usar un plugin que seguro que te limita de alguna manera.

Espero que esta ley cambie pronto para que esto sea innecesario, pero de mientras creo que esta es una solución fácil y sencilla.

Versión en video

Written by

David Morales

Computer Engineer

Teaching my software engineering knowledge in a creative way.

Would you like to get the 10 Ninja Keys of the Developer?

An exclusive PDF for Newsletter subscribers.

You will also be notified of future articles and affordable courses (in the pipeline) that will turn you into a ninja developer.

View privacy information

Leave a reply

Please fill in all fields.

Your email address will not be published.

View privacy information