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

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-sample
Code 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 install
Code language: Shell Session (shell)
Ahora crea un controlador Home con una plantilla index
:
rails generate controller Home index
Code 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 s
Code 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/[email protected]/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:

Y esta es la versión de 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 constructor crea la variable de clase donde guarda una referencia a la barra de cookies.
- El evento
init
comprueba si el usuario ya ha aceptado antes las cookies (aquí es donde se usaCookies.get
de la librería que has incluido del CDN). Si es así, se añade el código de Analytics. - Luego se añade el comportamiento a los botones en la barra.
- El método
addButtonBehaviors
comprueba si existe la barra de cookies. Recuerda que le indicaste a Rails que solo la mostrase si la cookie no estaba inicializada todavía. Por tanto, si no se muestra, el método retorna.- Si la barra existe, entonces se añade un Event Listener a cada botón, que llamará al método
allowCookies
. - El método
allowCookies
mira el argumento que has pasado e inicializa la cookieallow_cookies
al valor ‘yes’ o ‘no’, con una caducidad de 1 año. También, si el consentimiento se ha dado, se añade el código de Analytics.
- Si la barra existe, entonces se añade un Event Listener a cada botón, que llamará al método
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 aceptas las cookies, la barra desaparecerá, y el código de Analytics será añadido. Si refrescas la página, la barra no aparecerá porque la cookie se guarda en el navegador, y el código de Analytics se vuelve a añadir.
- Si rechazas las cookies, el código de Analytics no se añadirá, y la barra no volverá a aparecer hasta que elimines manualmente la cookie de tu navegador. Si refrescas la página, este comportamiento se mantendrá.
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.