ActiveAdmin es una potente gema para construcción de paneles de administración en ruby on rails, en este tutorial veremos como utilizar recursos anidados dentro de ActiveAdmin.
Paso 0: Setup
Para partir vamos a construir una aplicación web sencilla que tenga artistas, álbumes y canciones. Obviamente un artista puede tener varios álbumes y cada álbum puede tener varias canciones.
por lo que nuestros recursos quedarían de la siguiente forma: “Artist >> Album >> Songs”
Si queremos desde el panel de control subir una canción y que quede automáticamente asignada al artista o querer hacer acciones CRUD sobre las canciones, pero que deben estar bajo el contexto de un Album y Artista determinados. Este es justamente el ejemplo que vamos a revisar.
- Partiremos con un nuevo proyecto en Rails y agregaremos la gema ActiveAdmin siguiendo los pasos de la documentación.
- Luego generaremos nuestros tres modelos:
rails g model Artist name
rails g model Album name year artist:references
rails g model Song title composer time:time album:references
No olvidemos las relaciones en los modelos
class Artist < ActiveRecord::Base
has_many :albums
has_many :songs, through: :albums
end
class Album < ActiveRecord::Base
belongs_to :artist
has_many :songs
end
class Song < ActiveRecord::Base
belongs_to :album
end
El siguiente paso es generar los recursos en ActiveAdmin:
rails generate active_admin:resource Artist
rails generate active_admin:resource Album
rails generate active_admin:resource Song
Anidar los recursos en directamente en ActiveAdmin:
Para que ActiveAdmin sepa que necesitamos anidar los recursos generados, debemos indicar las relaciones en los mismos controladores de ActiveAdmin. En el caso de los álbumes tendríamos lo siguiente:
ActiveAdmin.register Album do
belongs_to :artist, optional: true
end
En el caso de las canciones debemos indicar que pertenece conjuntamente a un artista y álbum determinado:
ActiveAdmin.register Song do
controller do
nested_belongs_to :artist, :album, optional: true
end
end
La directiva optional permite que los recursos puedan ser accedidos directamente por la ruta /admin/songs y también por las rutas anidadas.
El último paso necesario para que todo esto funcione es generar las rutas anidadas en el archivo de rutas de la siguiente forma:
Rails.application.routes.draw do
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
namespace :admin do
resources :artists do
resources :albums do
resources :songs
end
end
end
namespace :admin do
resources :artists do
resources :songs
end
end
namespace :admin do
resources :albums do
resources :songs
end
end
root 'admin/dashboard#index'
end
El primer bloque de anidamientos genera las rutas paso a paso desde artistas, pasando por álbumes y finalmente las canciones. El segundo permite acceder directamente a las canciones de cada artista saltándonos los álbumes y el tercero podemos ver las canciones por cada álbum sin tener que pasar por los artistas.
Ahora podemos hacer uso de nuestros recursos anidados de muchas formas posibles. Veremos unas cuantas aplicaciones. En el archivo artist.rb modificaremos la vista index:
ActiveAdmin.register Artist do
permit_params :name
index do
selectable_column
column "Nombre", :name do |artist|
link_to artist.name, admin_artist_path(artist)
end
column "Albumes", :albumes_del_artista do |artist|
link_to artist.albums.count, admin_artist_albums_path(artist)
end
column "Canciones", :canciones_del_artista do |artist|
link_to artist.songs.count, admin_artist_songs_path(artist)
end
actions
end
member_action :songs do
@songs = Artist.find(params[:id]).songs
end
end
Esto nos permitirá ver un resumen de los discos y canciones que tiene cada artista y entrar al detalle de cada uno de ellos. Al final, la member action funciona como una acción en un controlador normal y cargará la vista view/admin/artists/songs.html.erb (Puedes usar vistas normales en layout de ActiveAdmin!! ).
Esto resultaría en algo como esto (recuerda crear algunos artistas, álbumes, y discos para jugar y probar las posibilidades):
En el caso de los álbumes podríamos tener algo de la siguiente forma:
ActiveAdmin.register Album do
belongs_to :artist, optional: true
permit_params :name, :year
index do
selectable_column
column "Nombre", :name do |album|
link_to album.name, admin_artist_album_path(album.artist,album)
end
column "Year", :anio_del_album do |album|
link_to album.year, admin_artist_album_path(album.artist,album)
end
column "Canciones", :canciones_del_album do |album|
link_to album.songs.count, admin_album_songs_path(album)
end
actions
end
end
Y para terminar podemos mostrar nuestras canciones asi:
ActiveAdmin.register Song do
controller do
nested_belongs_to :artist, :album, optional: true
end
permit_params :title, :composer, :time
index do
selectable_column
column "Nombre", :title
column "Compositor", :composer
column "Tiempo", :time do |t|
t.time.strftime('%M:%S')
end
actions
end
end
Como hemos visto, la posibilidad de anidar nuestros recursos en ActiveAdmin nos permite reflejar de mejor manera la lógica de nuestros procesos y estructura de nuestra información. Además, con las acciones custom podemos extender el funcionamiento de ActiveAdmin para agregar nuevos métodos y vistas.
Puedes descargar el código de este tutorial en el siguiente link: https://github.com/sbstn-jmnz/active_admin_example
Si después quieres hacer scaffolds en tus proyectos con ActiveAdmin, no olvides revisar el siguiente tutorial. Te puede salvar de un dolor de cabeza:
http://blog.desafiolatam.com/como-hacer-un-scaffold-despues-de-instalar-activeadmin/