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!! ).

Songs

Esto resultaría en algo como esto (recuerda crear algunos artistas, álbumes, y discos para jugar y probar las posibilidades):

Artistas

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/