Añade etiquetas a un modelo con Ruby on Rails
Aprovecho que he añadido etiquetas al blog para explicar lo fácil que ha sido hacerlo con Ruby on Rails. Si tienes curiosidad por ver el código en profundidad, puedes ver la PR en Github. Se me fue un poco la mano y acabé añadiendo estilos y tests que faltaban por ahí.
Lo primero son los modelos. La manera fácil de hacerlo es usando has_and_belongs_to_many pero en el futuro quiero poder etiquetar cualquier modelo, así que me he decidido por usar un modelo intermedio en el que en el futuro migraré a una asociación polimórfica (exacto, Yagni).
Los modelos asociados quedan así:
class Entry < ApplicationRecord
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
end
class Tag < ApplicationRecord
has_many :taggings, dependent: :destroy
has_many :entries, through: :taggings
end
class Tagging < ApplicationRecord
belongs_to :entry
belongs_to :tag
end
De esta manera es super fácil acceder a las etiquetas desde una entrada (Entry.first.tags
) o ver todas las entradas etiquetadas con una determinada etiqueta (Tag.first.entries
).
Asociando desde la UI
He creado la sección correspondiente del panel de administración para añadir/editar/eliminar etiquetas.
Al añadir/editar una entrada se muestra una lista de etiquetas con un checkbox al lado para seleccionar las que quiera. Rails hace que esto sea extremadamente simple. Tanto el mostrar la lista de etiquetas como el asociarlas directamente al crear/actualizar una entrada.
Lo primero es actualizar los parámetros permitidos en el controlador. Como se pueden asociar varias etiquetas, esta es la sintaxis a usar:
params.expect(entry: [ :title, ..., tag_ids: [] ])
En el formulario de las entradas he usado este helper que se encarga de mostrar todas las etiquetas con un checkbox para seleccionarlas.
<%= form.collection_checkboxes(:tag_ids, Tag.all, :id, :name) %>
El resultado no es el más bonito del mundo, pero necesito que funcione todo sin Javascript. Tengo algunas ideas para mejorar progresivamente usando turbo-frames y autocompletar, para poder añadir nuevas etiquetas directamente desde el formulario.
El helper acepta diferentes parámetros y hasta bloques, permitiendo personalizar cómo se ven las etiquetas. Por ejemplo, para la barra lateral el código luce tal que así:
<%= form.collection_checkboxes(:tags, Tag.all, :name, :name, include_hidden: false, checked: params[:tags]) do |b| %>
<%= b.label { b.checkbox + b.text } %>
<% end %>
Comentarios
Nadie ha comentado nada por ahora.