General
Última actualización
Última actualización
Es una gema que utilizamos como back office.
La utilizamos porque resuelve rápidamente los típicos CRUD de admin. Con ActiveAdmin en unos minutos puedes tener para un recurso (modelo ActiveRecord): el menu para acceder, las vistas para crear/editar, el listado paginado con filtros y varias cosas más.
La gema viene instalada si el proyecto se generó usando Potassium. Si no es así, igual puedes agregarlo luego ejecutando potassium install admin
.
Supongamos que tenemos el modelo Blog
con los atributos title
, body
y user
(owner del Blog). Si agregamos bajo /app/admin/blogs.rb
el siguiente código:
Al acceder a http://localhost:3000/admin/blogs
veremos el listado de blogs:
y si hacemos clic en el link "Editar" de alguno de los blogs veremos el formulario:
Listo! Eso es todo lo que necesitas hacer para tener algo funcionando. De todos modos, en un proyecto Platanus comúnmente verás algo como esto:
para tener más control de lo que se quiere mostrar. Por ejemplo, así se ve el index con la configuración custom:
Active Admin toma la configuración de locales de Rails para traducir los nombres de las columnas. Por ejemplo, para traducir los atributos de Blog
deberías tener la siguiente configuración:
/config/locales/es-CL.yml
De esta manera al entrar por ejemplo la vista de un Blog
verás los atributos traducidos:
Ten en cuenta que también funciona con métodos (getters) custom. Por ejemplo, podrías tener:
/app/models/blog.rb
/config/locales/es-CL.yml
/app/admin/blogs.rb
y funcionará.
Agrupar recursos
Para agrupar varios items dentro de un mismo menú, debes:
Definir el menú en el initializer de active admin:
/config/initializers/active_admin.rb
Definir en el recurso su menú padre:
/app/admin/blogs.rb
Ocultar menú
Se hace de la siguiente manera:
/app/admin/blogs.rb
A simple vista parece no tener mucha utilidad pero lo importante aquí es que aunque no exista el menú, igual existen los endpoints. Algo que puede ser conveniente si queremos usar alguna ruta del admin como una API.
Menú condicional
Puede ser útil mostrar u ocultar un menú dependiendo de una condición. El caso más típico es el de roles. Por ejemplo:
/app/admin/blogs.rb
En Platanus usamos Active Admin con el adapter de Pundit para autorizar recursos. Si al registrar un nuevo recurso en AA, no tienes creado el policy de ese recurso, observarás un error así:
Si esto ocurre, agrega el policy correspondiente y define los permisos para cada una de las acciones del CRUD:
Si todavía no estás en la instancia del proyecto en la cual tienes que preocuparte por permisos deja todas las acciones en true.
Es importante mencionar que si una acción no tiene permisos, esta desaparecerá del menú y links, etc. Por ejemplo:
Al tratar de acceder a http://localhost:3000/admin/blogs/303
Se puede ver además como el link a "Ver" desapareció:
Los action_item
s son botones que se pueden agregar a las vistas del recurso. Por ejemplo, el siguiente código mostrará un botón (link), solo en la vista index
, para ir al listado de administradores.
Ten en cuenta que puedes decidir en qué vistas aparecerá el botón usando la opción only.
Las member_action
s son acciones extra que se pueden agregar al controller del recurso. Por ejemplo, el siguiente código:
sumará el endpoint /admin/blogs/:id/send_mail
a los endpoints del CRUD.
Ten en cuenta que se puede utilizar action_item
s para ejecutar estas nuevas acciones. Por ejemplo, el siguiente código agregará un botón en la vista del blog (show
) desde el que se llamará a la acción send_mail
.
Una alternativa a los action_item
s es agregar la acción al listado del index así:
Es lo mismo que una member_action
pero sin apuntar a un recurso en particular sino a la colección. Por ejemplo, la siguiente member_action
:
creará el siguiente endpoint: POST /admin/blogs/:id/send_mail
. En cambio, esta collection_action
:
generará este: POST /admin/blogs/send_mails
La idea entonces con esto es que las member_action
s se usen junto a action_item
s en show
, new
y update
y las collection_action
con action_item
s en el index
.
Ten en cuenta que dentro de una member_action podrás acceder al recurso actual (en nuestro ejemplo un Blog de id x) usando el método resource. En cambio, en una collection_action, podrás acceder al listado de recursos (lista de Blogs en el ejemplo), que está mostrando el index en ese momento, usando el método collection.
Si prestaste atención a la imagen del formulario de la sección "Uso básico", seguro notaste que el selector de usuarios no muestra correctamente el nombre de los mismos:
esto se debe a que Active Admin espera que los recursos tengan definido el método: :display_name
para que puedan ser representados como "String". Si el recurso no lo implementa, simplemente llamará a to_s
mostrando como resultado lo que vemos en el selector. Entonces, para solucionar esto, podemos hacer lo siguiente:
Ten en cuenta que display_name (o cualquiera de las otras opciones) se utilizará en varios lugares: en el título de un recurso, en los links de las rows/columns y, como vimos, en los selectores.
Hay veces que necesitamos agregar nuevos endpoints con HTML a medida. Para hacer esto hacer lo siguiente:
Agregar la member_action
:
Agregar el action_item
:
Agregar la vista custom:
Agregamos el HTML para nuestra nueva member_action
en /app/views/admin/blogs/preview.html.erb
Ten en cuenta que puedes agregar el archivo con extensión .arb
en vez de .erb
y usar la gema Arbre que es el DSL que Active Admin utiliza para dibujar sus vistas. El siguiente código:
/app/views/admin/blogs/preview.html.arb
sería equivalente a lo de /app/views/admin/blogs/preview.html.erb
en Arbre.
Para manejo de archivos se supone el uso de Shrine
Suponiendo que el blog tiene un archivo image
:
Agregar la member_action
:
Agregar el action_item
:
Agregar link a las actions
en el index
Si necesitas agregar alguna pequeña inteligencia en una vista de Active Admin revisa nuestra guía sobre AlpineJS.
Es una gema construida en Platanus sobre Active Admin y la utilizamos para facilitar algunas features comunes. Por ejemplo: inputs con select2, selector de booleanos en index/show, selector de colores, etc.
Muchas veces en un formulario de Active Admin necesitamos un input custom. Por ejemplo: selectores de moneda, de colores, con búsqueda ajax, etc. Por esto, Active Admin ofrece una forma sencilla de agregar estos controles. Para mostrarte cómo funciona te mostraré en pasos como agregar un input que escribe con console.info
lo que se escribió en input en el evento focus out.
Agregar el archivo con mi input en /app/inputs/logger_input.rb
.
Ten en cuenta que el nombre del archivo debe tener la forma: [nombre_control]_input y lo mismo para el nombre de la clase, pero en CamelCase.
Agregar el js con la lógica del focus out en /app/assets/javascripts/admin/inputs/logger_input.js
Incluir el js en /app/assets/javascripts/active_admin.js
:
Usar en el form:
Para manejar la búsqueda de los filtros ActiveAdmin por debajo usa Ransack. Esta gema usa distintos sufijos para indicar distintos tipos de búsqueda. Además, nos permite hacer búsquedas con respecto a atributos de asociaciones.
Por ejemplo, si queremos buscar blogs por nombre de usuario:
Aquí _cont
indica que se entregarán los resultados que contengan el valor dado. Podríamos haber usado _eq
si quisieramos un match perfecto, por ejemplo.
Muchas veces lo que se puede hacer con AA es un poco riguroso en cuanto a las necesidades del cliente, por lo que pueden haber situaciones en las cuales necesitemos incorporar Vue.js en AA. A continuación se explica una guía paso a paso de cómo agregar este en AA.
Para esto tenemos 2 opciones:
Hacer una vista custom como se mencionó anteriormente y ahí usar Vue.
Usar directamente un componente en la vista de admin o en un vista html.arb.
Se crea el componente vue que queremos utilizar, por ejemplo massive-edit.vue
.
Luego debemos registrar el componente globalmente. Acá necesitamos usar un archivo diferente al application.js
que utilizamos normalmente, para este caso usaremos un archivo llamado admin_application.js
que se debe encontrar en la misma carpeta que el application.js
, si no se encuentra debe crearlo, la convención para registrar los componentes que se usan en admin es de snake_case
, siguiendo con el ejemplo anterior el archivo se vería así:
Si queremos utilizar filtros, i18n o tailwind en los archivos Vue que utilizaremos en AA, debemos importarlos en este archivo también, tal como lo hacemos normalmente. Cabe destacar que si tenemos algo importado en application.js
no va a funcionar en los componentes que se utilicen en AA, si no que debemos importarlos nuevamente en admin_application.js
, acá un ejemplo del archivo completo:
Luego podemos ir a cualquier vista dentro de app/views/admin
y usar el componente como lo hacemos normalmente:
Hacer los mismos pasos anteriores.
Instalar la clase vue_component
desde nuestra gema potassium. Esto agrega un par de inicializadores a nuestra app. Se debe escribir potassium install
y escoger vue_component
.
Luego en el archivo initializers/active_admin.rb
debemos importar vue_componment
y hacer build del componente registrado anteriormente:
La función component_creator recibe los nombres de los componentes y los convierte a html que puede procesar AA mediante la gema Arbre. Lo anterior se debe poner fuera del ActiveAdmin.setup
.
Utilizar el componente en la vista, puede ser de las siguientes formas:
a. html.arb:
b. admin