#284 Active Admin
- Download:
- source codeProject Files in Zip (97.3 KB)
- mp4Full Size H.264 Video (24 MB)
- m4vSmaller H.264 Video (14.9 MB)
- webmFull Size VP8 Video (20.4 MB)
- ogvFull Size Theora Video (35.1 MB)
Vamos a dedicar este episodio a Active Admin, que es una gema con la que podemos añadir fácilmente una interfaz de administración a nuestras aplicaciones Rails. La interfaz que se genera tiene un aspecto cuidado y muy personalizable. Se puede ver en acción entrando en la demo en vivo.
En este episodio vamos a integrar Active Admin sobre una aplicación Rails ya existente. La aplicación con la que trabajaremos es una aplicación muy sencilla de comercio electrónico que tiene varios productos, cada uno de ellos con su precio y categoría. Utilizaremos ActiveAdmin para crear una interfaz de administración que permita gestionar nuestros productos.
Instalación de Active Admin
Active Admin es una gema que se instala, como es habitual, añadiendo una referencia en el Gemfile
y ejecutando a continuación bundle
. La aplicación es una aplicación Rails 3.1 por lo que debemos asegurarnos de incluir la gema sass-rails
porque Active Admin depende de ella. En Rails 3.0 no nos haría falta incluirla.
gem 'activeadmin'
Una vez que Bundler ha terminado, para añadir Active Admin tenemos que ejecutar un generador en nuestra aplicación. Este generador además nos dará instrucciones adicionales que podremos configurar después. Tenemos que añadir la opción host
a la configuración del correo en el entorno de desarrollo y asegurarnos de que tenemos una URL raíz y mostramos los mensajes notice
y alert
en el layout de la aplicación.
$ rails g active_admin:install invoke devise generate devise:install create config/initializers/devise.rb create config/locales/devise.en.yml ================================================================== Some setup you must do manually if you haven't yet: 1. Setup default url options for your specific environment. Here is an example of development environment: config.action_mailer.default_url_options = { :host => 'localhost:3000' } This is a required Rails configuration. In production it must be the actual host of your application 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root :to => "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p>
Nosotros ya tenemos todo esto en nuestra aplicación por lo que podemos continuar.
La orden también crea alguna migraciones que tenemos que ejecutar.
$ rake db:migrate
Uso de Active Admin
En la documentación de Active Admin se indica que durante la migración inicial se creará un usuario con el nombre admin@example.com
y la clave password
. Podemos iniciar la sesión con estos credenciales (por supuesto estos valores se pueden modificar editando el fichero de migración devise_create_admin_users.rb
antes de lanzar las migraciones) Visitando http://localhost:3000/admin con el servidor Rails en marcha veremos un formulario de inicio de sesión donde podemos introducir dichas credenciales.
Tras el inicio de sesión seremos llevados al cuadro de mandos de Active Admin, donde no encontraremos mucho que ver.
Como queremos gestionar nuestros productos añadiremos el recurso Product
a Active Admin ejecutando la orden:
$ rails g active_admin:resource product create app/admin/products.rb
Este generador crea un fichero llamado products.rb
bajo el directorio app/admin
de la aplicación. Si refrescamos el cuadro de mandos de la aplicación ahora veremos un enlace con el texto “Products” y si hacemos clic iremos a una página que tiene todo lo necesario para gestionar los productos.
En la página hay opciones para ordenar o filtrar el listado de productos por cualquier atributo. Active Admin detectará incluso las relaciones belongs_to
con Category
e implementará un menú desplegable para poder filtrar los productos por dicha categoría. Esto también ocurre cuando creamos un nuevo producto y se muestra un desplegable para escoger la categoría. El resto de atributos tendrán campos de entrada acordes con su tipo de datos.
Esta funcionalidad es fácil de modificar. Empecemos personalizando el índice de productos quitando columnas. Para ello modificaremos el fichero /app/admin/products.rb
anteriormente generado. Podemos cambiar el listado principal redefiniendo el método index
. Este método recibe un bloque dentro del cual podemos especificar las columnas que deseamos ver en la página invocando a column
.
ActiveAdmin.register Product do index do column :name column :category column :released_at column :price end end
Si recargamos la página de productos veremos que ahora muestra sólo las columnas que queremos.
Obsérvese que la asociación con Category
ha sido detectada automáticamente y junto a cada producto se muestra la categoría correcta.
Podemos ir más lejos y cambiar el título de la columna pasando el título como primer argumento. Cambiaremos de esta forma el campo released_at
.
ActiveAdmin.register Product do index do column :name column :category column "Release Date", :released_at column :price end end
Si queremos cambiar los valores de una columna podemos hacerlo pasando un bloque a column
. El campo de precio no muestra un símbolo monetario, pero podemos cambiarlo para que lo haga. El método column
puede recibir un bloque, en cuyo caso se le pasaría la instancia (en este caso un Product
) y se mostraría en la columna lo que devuelva el bloque. Aquí tenemos acceso a los métodos helper por lo que podemos utilizar number_to_currency
para mostrar correctamente el precio.
ActiveAdmin.register Product do index do column :name column :category column "Release Date", :released_at column :price do |product| number_to_currency product.price, :unit => "£" end end end
Si recargamos la página veremos el título modificado y el precio correcto para cada producto.
Pero si personalizamos el valor devuelto para el campo price
entonces ya no podemos ordenar por dicho campo, y tampoco tenemos enlaces de edición y borrado para cada elemento. Esto lo tenemos que corregir, siempre que usemos un bloque para personalizar un valor también debemos usar la opción :sortable
para que Active Admin sepa cómo ordenar la columna. Añadiremos también default_actions
para que vuelvan a aparecer los enlaces de edición y borrado.
ActiveAdmin.register Product do index do column :name column :category column "Release Date", :released_at column :price, :sortable => :price do |product| number_to_currency product.price, :unit => "£" end default_actions end end
En el campo de precio ahora se muestra el símbolo monetario pero sería mejor poder alinear los valores a la derecha. Esto lo podemos hacer con CSS, pero para eso tenemos que poder identificar la columna. Active Admin proporciona una manera de generar HTML muy similar a Markaby, tan sólo tenemos que llamar un método con el nombre de la etiqueta que deseamos generar. Podemos pasar la opción :class
para que la etiqueta tenga algo que podamos controlar desde CSS.
ActiveAdmin.register Product do index do column :name column :category column "Release Date", :released_at column :price, :sortable => :price do |product| div :class => "price" do number_to_currency product.price, :unit => "£" end end default_actions end end
Ya podemos dar estilos a esta columna modificando el fichero active_admin.css.scss
.
// Active Admin CSS Styles @import "active_admin/mixins"; @import "active_admin/base"; // To customize the Active Admin interfaces, add your // styles here: .price { text-align :right; }
Y la columna con precios se alineará correctamente.
Ámbitos
Otra interesante funcionalidad de Active Admin son los ámbitos, que se comportan como filtros predefinidos. Para crear estos ámbitos hay que seguir dos pasos. Primero añadimos una llamada a scope
en el fichero de configuración de nuestros productos, pasándoles el nombre de un ámbito.
ActiveAdmin.register Product do scope :unreleased index do column :name column :category column "Release Date", :released_at column :price, :sortable => :price do |product| div :class => "price" do number_to_currency product.price, :unit => "£" end end default_actions end end
Y luego necesitamos escribir dicho ámbito en el modelo correspondiente:
class Product < ActiveRecord::Base belongs_to :category scope :unreleased, where(:released_at => nil) end
Si ahora volvemos a cargar la página de administración de productos veremos listado el ámbito. Si hacemos clic en él veremos un listado de productos filtrado por dicho ámbito.
Personalización del cuadro de mandos
A continuación veremos cómo personalizar el cuadro de mandos. Por defecto aparece vacío, así que mostraremos un listado de los productos más recientes, lo que haremos modificando el fichero /app/admin/dashboards.rb
. En los comentarios del archivo se documentan las posibilidades de las que disponemos.
Para añadir una sección al cuadro de mandos se utiliza el método section
. Queremos enumerar los productos más recientes en una tabla, lo que podemos hacer con table_for
. En el bloque podemos definir qué columnas queremos mostrar con column
de la misma forma que hicimos cuando personalizamos el índice de productos. También añadiremos un enlace a la página que muestra todos los productos.
ActiveAdmin::Dashboards.build do section "Recent Products" do table_for Product.order("released_at desc").limit(5) do column :name column :released_at end strong { link_to "View All Products", admin_products_path } end end
Si ahora recargamos el panel de control veremos los cinco productos más recientes, así como el enlace.
La página sería más útil si cada producto del listado enlazase a la página de administración de dicho producto. Esto lo podemos hacer pasándole un bloque al método column
, igual que hicimos con la columna price
anteriormente.
ActiveAdmin::Dashboards.build do section "Recent Products" do table_for Product.order("released_at desc").limit(5) do column :name do |product| link_to product.title, admin_product_path(product) end column :released_at end strong { link_to "View All Products", admin_products_path } end end
Hay una forma más breve de definir una ruta en link_to
. En lugar de utilizar admin_product_path(product)
podemos pasar un array con un símbolo como primer elemento y el producto como el segundo:
link_to product.title, [:admin, product]
Si recargamos el cuadro de mandos veremos el título de cada producto como un enlace que nos llevará a la página correspondiente de administración de dicho producto.
Ajustes en las hojas de estilo
Hay un problema que debemos tener en cuenta cuando utilizamos Active Admin en Rails 3.1, que podemos ver volviendo al sitio principal.
La página no tiene el aspecto que tenía antes porque ahora se incluye en todas las páginas la hoja de estilos de Active Admin. Rails 3.1 incluye todas las hojas de estilos por defecto, debido a la presencia de la línea con require_tree .
en el fichero de manifiesto de application.css
. Como esto no es lo que queremos (y además siempre es buena idea hacerlo para tener más control sobre los estilos de nuestras aplicación) vamos a cambiar require_tree .
por require products
.
/* * This is a manifest file that'll automatically include all the stylesheets available in this directory * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at * the top of the compiled file, but it's generally better to create a new file per style scope. *= require_self *= require products */ /* Se omite el resto del archivo */
Una solución todavía mejor es pasarnos a la orden import
de SASS. Podemos hacer que el fichero CSS de nuestra aplicación sea SASS añadiendo la extensión .scss
a su nombre. Luego podemos quitar el manifiesto de la parte superior y añadir al final la orden import
:
/* (Se omiten los estilos)*/ @import "products";
Si recargamos la página principal sólo se incluyen las páginas de estilos correspondientes y la página tiene el aspecto correcto.
Configuración global
Hay otro archivo para configurar Active Admin en el directorio /config/initializers
donde hay bastantes opciones de configuración que aparecen comentadas. Una que no lo está es el fichero con el título del sitio, que cambiaremos.
ActiveAdmin.setup do |config| # == Site Title # # Set the title that is displayed on the main layout # for each of the active admin pages. # config.site_title = "Eifion's Store" # (Se omiten otras opciones de configuración) end
Para que estos cambios surtan efecto debemos reiniciar el servidor, tras hacerlo aparecerá el título correcto.
Con esto terminamos este episodio. Hay muchas más cosas que se pueden adaptar en Active Admin y que no hemos repasado hoy, merece la pena ver la documentación para ver qué más cosas podemos hacer. Podemos modificar el aspecto y la funcionalidad de todas las páginas de Active Admin para adaptarlas a nuestras necesidades, por lo que es una solución muy poderosa para añadir la funcionalidad de administración en nuestras aplicaciones Rails.