Parche para Rails: Rutas predeterminadas en español

Hace poco en Rails edge agregaron la opción de crear rutas para recursos con nombre de controlador y ruta del controlador distintas. Me explico mejor así:

RUBY:

  1. map.resources :messages, :as => ‘mensajes’

  2. # Antes para obtener algo similar hacias esto (y esto no creaba una ruta "RESTful"):

  3. map.connect ‘mensajes/:id/:action’, :controller => ‘messages’

Esto te permite tener rutas como /mensajes/... en lugar de /messages/... y a la vez aprovechando métodos “RESTful”.

El problema ahora era que tendrias rutas como ”/mensajes/new” y ”/mensajes/edit”... eso no se ve muy bien.

Pregunte en la lista de Rails Core y me dijeron que podía crear un parche, y es lo que hice, pero ahora necesito que lo prueben y voten por el para que lo incluyan en Rails. Aquí esta el ticket:

http://dev.rubyonrails.org/ticket/11181

Si no tienen inconvenientes, agregen un comentario con el texto ”+1”.

Bueno, todavía ni he explicado como funciona. Al aplicar el parche, tienes dos opciones para cambiar los nombres de las rutas:

RUBY:

  1. # En environment.rb:

  2. config.action_controller.resources_path_names = { :new => ‘nuevo’, :edit => ‘editar’ }

  3.  

  4. # En routes.rb:

  5. map.resources :schools, :as => ‘escuelas’, :path_names => { :new => ‘nueva’ }

Como vez, puedes definir los nombres predeterminados en environment.rb, pero luego puedes sobreescribirlos en tus rutas.

Script para abrir Konsole con pestañas para Rails

Bueno, ya que voy encarrerado…

Esto lo dividí en 2 scripts porque si lo hago en uno, en mi máquina no me funciona (kGutsy x64)...

rails_konsole:

CODE:

  1. #!/bin/bash

  2. PIDS=`pidof konsole`

  3.  

  4. konsole—script &

  5.  

  6. ARGS=“”

  7. for pid in $PIDS; do

  8.   ARGS=”${ARGS} -o ${pid}”

  9. done

  10. PID=`pidof ${ARGS} konsole`

  11.  

  12. sleep 2

  13.  

  14. application=“Application”

  15. if [ -n ”$1” ]; then

  16.   application=”$1”

  17. fi

  18.  

  19. dcop konsole-${PID} session-1 renameSession $application

  20.  

  21. dcop konsole-${PID} konsole newSession

  22. dcop konsole-${PID} session-2 renameSession Server

  23.  

  24. dcop konsole-${PID} konsole newSession

  25. dcop konsole-${PID} session-3 renameSession Console

  26.  

  27. dcop konsole-${PID} konsole newSession

  28. dcop konsole-${PID} session-4 renameSession AutoTest

  29.  

  30. rails_konsole_dcops $PID

rails_konsole_dcops:

CODE:

  1. #!/bin/bash

  2. dcop konsole-${1} konsole activateSession session-1

  3.  

  4. dcop konsole-${1} session-2 sendSession “ruby script/server”

  5. dcop konsole-${1} session-3 sendSession “ruby script/console”

  6. dcop konsole-${1} session-4 sendSession “autotest -rails”

Vaya, se ve horrible y hay un error. Asegúrate de copiar la versión de texto plano y cambiar el guión largo antes de “script” por dos guiones cortos… si ya se, que flojera.

Básicamente lo que hace es que al ejecutar ‘rails_konsole’, te abre una instancia de Konsole con cuatro pestañas, una libre, una ejecutando script/server, otra script/console, y la última para autotest (gem install zentest).

Esto lo ejecutas en el directorio de tu aplicación, y opcionalmente le pasas el nombre de tu aplicación como parámetro (rails_konsole MiApp) para que le de el nombre apropiado a la primer pestaña (para que no te confundas si tienes abiertos varios proyectos).

Plantilla NetBeans para controladores REST

¿A que creyeron que estaba muerto? Pues no… Esto de tener un trabajo y aparte mantener un blog me parecia mucho más fácil antes de iniciarlo…

En fin, les paso una plantilla para NetBeans que sirve para generar una serie de acciones REST estándar. Tu solo necesitas introducir dos variables y el nombre del modelo.

La idea (y práctiamente todo el código) me la robe de Softies on Rails.

“Behold”:

RUBY:

  1. def index

  2.   @${items} = ${Model}.find :all

  3.  

  4.   respond_to do |format|

  5.     format.html # index.html.erb

  6.     format.xml  { render :xml => @${items} }

  7.   end

  8. end

  9.  

  10. def show

  11.   @${item} = ${Model}.find(params[:id])

  12.  

  13.   respond_to do |format|

  14.     format.html # show.html.erb

  15.     format.xml  { render :xml => @${item} }

  16.   end

  17. end

  18.  

  19. def new

  20.   @${item} = ${Model}.new

  21.  

  22.   respond_to do |format|

  23.     format.html # new.html.erb

  24.     format.xml  { render :xml => @${item} }

  25.   end

  26. end

  27.  

  28. def edit

  29.   @${item} = ${Model}.find(params[:id])

  30. end

  31.  

  32. def create

  33.   @${item} = ${Model}.new(params[:${item}])

  34.  

  35.   respond_to do |format|

  36.     if @${item}.save

  37.       flash[:notice] = ’$2 was successfully created.’

  38.       format.html { redirect_to(@${item}) }

  39.       format.xml  { render :xml => ${item}, :status => :created, :location => ${item} }

  40.     else

  41.       format.html { render :action => “new” }

  42.       format.xml  { render :xml => @${item}.errors, :status => :unprocessable_entity }

  43.     end

  44.   end

  45. end

  46.  

  47. def update

  48.   @${item} = ${Model}.find(params[:id])

  49.  

  50.   respond_to do |format|

  51.     if @${item}.update_attributes(params[:${item}])

  52.       flash[:notice] = ’${Model} was successfully updated.’

  53.       format.html { redirect_to(@${item}) }

  54.       format.xml  { head :ok }

  55.     else

  56.       format.html { render :action => “edit” }

  57.       format.xml  { render :xml => @${item}.errors, :status => :unprocessable_entity }

  58.     end

  59.   end

  60. end

  61.  

  62. def destroy

  63.   @${item} = ${Model}.find(params[:id])

  64.   @${item}.destroy

  65.  

  66.   respond_to do |format|

  67.     format.html { redirect_to(admin_${items}_url) }

  68.     format.xml  { head :ok }

  69.   end

  70. end

Por ahí le falta una arroba (@) en la acción “create”. Sí se la puse, pero ahi arriba no se porque no aparece. Consideralo un acertijo.

Documentando tu aplicación Rails

Hoy leí algo muy interesante para documentar mockups o diseños de interfase usando algo llamado Documentos de Descripción del Diseño (o algo así).

Me pareció muy interesante, y se me ocurrió implementarlo para documentar código fuente de Rails.

Creo que este tipo de documentación puede ser muy útil cuando estas desarrollando, o incluso para mostrar un prototipo al cliente, porque puede ver muy fácilmente que esperar que haga la aplicación en cada paso.

Escribí un crudo plugin para hacer esto, y su objetivo es documentar las acciones de los controladores. Espero esta imagen te lo explique mejor:

Pantalla de panel RD3

Ese panel aparece en todas las acciones que tienen documentación definida. En el ejemplo anterior podría ser así:

RUBY:

  1. class SesionesController

  2.   # DD: Validar credenciales de usuario.

  3.   def iniciar_sesion

  4.     # DD: Inicio de sesión:

  5.     # # El usuario escribe su login y clave de acceso

  6.     # # El usuario da clic en el botón "Iniciar sesión"

  7.     # # El sistema válida la información. Si es correcta el usuario es llevado a su cuenta.

  8.     hacer_algo_util

  9.     # DD: Errores:

  10.     # p. El usuario escribe un login incorrecto

  11.     # # Se muestra un error en el campo de login

  12.     # DD: El usuario escribe una clave incorrecta

  13.     # # Se muestra un error en el campo de clave

  14.     mas_codigo_rails

  15.     etc

  16.   end

  17. end

El panel puedes arrastrarlo por la pantalla, “minimizarlo” (doble clic en el título), o cerrarlo por completo (X).

Escribí el plugin muy rápido, así que esta horrendo. Quiero escuchar opiniones antes de “embellecerlo”. Notarán quienes tengan experiencia escribiendo “parsers” que yo no la tengo, así que una ayudadita no caería mal :-)

La instalación no es tan rápida como la de otros plugins, pero de momento creo que es suficiente. Primero baja este archivo y descomprimelo en la carpeta vendor/plugins. Dentro de vendor/plugins/rd3/lib encontrarás una hoja de estilo. Copiala a public/stylesheets.

Luego en el layout de cada controlador (o en el de la aplicación), agrega lo siguiente en la sección *“head”*:

RUBY:

  1. <%= stylesheet_link_tag 'rd3' %>

  2. <%= javascript_include_tag :defaults %>

Ahora escribe la documentación que quieras para tus controladores con la siguiente guía:

RUBY:

  1. class SesionesController

  2.   # DD: Descripción de la acción.

  3.   def iniciar_sesion

  4.     # DD: Documentación sobre la acción

  5.     # Este comentario es parte del anterior.

  6.     codigo

  7.     # DD: Otra sección de documentación

  8.     # p. Acepta formato de RedCloth

  9.     # # Esta es una lista

  10.     # # Otro elemento

  11.     mas_codigo

  12.     # Este es un comentario normal que no será incluido

  13.     # en la documentación generada.

  14.   end

  15. end

Bien, ya que tienes tu controlador documentado, en la consola ejecutas una tarea de rake:

CODE:

  1. rake rd3:update

Eso creará unas vistas en doc/rd3, que serán las que aparecen en el panel.

Puedes personalizar este panel ya sea con el archivo CSS incluido o editando la plantilla rd3/lib/panel.erb.

Ah, casi lo olvidaba, este plugin solo se carga cuando estas en ambiente de desarrollo. En producción por supuesto ya no.

Agradeceré cualquier crítica que me puedan ofrecer :-)

Vlad the Deployer!

Jajaja, que nombrecito… Me recuerda al Sr. Arnold Schwaquiensabeque.

La forma “estándar” de publicar una aplicación Rails (o cualquier otra cosa en realidad), es con Capistrano. Solo es necesario escribir unas “recetas” simples para tu aplicación (que no son más que configuraciones, y algunos comandos, como el servidor a donde se va a publicar, entre otras cosas).

Luego desarrollas tu aplicación como siempre, y cuando quieres probar en un servidor que configuraste, simplemente le das un “cap deploy”, y se hace todo el trabajo por ti.

Algunos desarrolladores creen que Capistrano se esta volviendo muy complejo, y ya no les gusta trabajar con el. No estamos hablando de cualquier equipo de desarrollo, no.

Este equipo estrella ha creado la máquina de matar Vlad the Deployer! para asesinar a Capistrano.

Que risa me dio al ver el nombre. Y su página también es muy humorística. Nada más queda ver quien gana la batalla, porque además no se están metiendo con cualquiera.

Aplicaciones de escritorio con Shoes

Ya tiene tiempo que conocía Shoes pero había olvidado escribir sobre esto.

Shoes es como un framework, pero en vez de desarrollar aplicaciones web, es para aplicaciones de escritorio, con toques de funcionalidad web. Mira esto:

Chunky Bacon! with Shoes!

RUBY:

  1. Shoes.app do

  2.   background “rgb(102, 102, 102)”

  3.   stroke 0, 0, 0

  4.   x, y = nil, nil

  5.   motion do |_x, _y|

  6.     if x and y and (x != _x or y != _y)

  7.       append do

  8.         line x, y, _x, _y

  9.       end

  10.     end

  11.     x, y = _x, _y

  12.   end

  13. end

Esa, es TODA la aplicación. Los demás ejemplos de Shoes son igual de simples (y sorprendentes).

Shoes es además el alma de Hackety Hack.

Puedes instalar Shoes en Linux, Windows, y Mac OS. Para Linux es así de fácil (y para Mac es muy similar):

  • $ wget http://code.whytheluckystiff.net/dist/shoes-0.r117-linux.tar.gz
  • $ tar zxf shoes-0.r117-linux.tar.gz
  • $ cd shoes-0.r117
  • $ ./shoes samples/draw.rb

    En Windows:

    Muchos clics para bajar y descomprimir el archivo, luego abres un interprete de comandos, te cambias a la carpeta donde lo descomprimiste y ejecutas así “shoes samples\timer.rb” :-)

Aprende Ruby con Hackety Hack

Hay un programa para aprender Ruby muy sencillo y muy bueno llamado Hackety Hack.

Esta solo en inglés, y solo para Windows (de momento), pero seguro que a más de uno le podría servir. Para mi hubiera sido una gran diferencia tener un programa así cuando estaba aprendiendo Ruby.

Si sabes inglés, te puede ser muy útil para enseñar a programar a tu hermano menor :)

Grupo Ruby & Rails México

Nada más quiero informarles a quienes no lo conozcan que existe un grupo de Google llamado Ruby SIG Mexico al que podríamos dar más vida.

Yo ya estoy suscrito y para impulsar esto trataré de ayudar a quienes pongan cualquier pregunta en el grupo.

Si tienes algún interés en difundir Ruby en México, no dudes en aportar con preguntas o respuestas.

[OT] “Skin” oscura para Google Reader

Hace tiempo que modifique varios estilos de Google Reader y los combine en algo que me ha agradado bastante, así que lo comparto con ustedes.

Para mi es mucho más fácil de leer, y ofrece más espacio para tus feeds.

Tiene varios problemillas menores con algunos colores, pero nada grave.

Necesitas la extensión Stylish para Firefox. Para cualquier otro navegador… suerte :)

Google Reader Dark OSX.

Google Reader Dark OSX

Ruby te hace un mejor desarrollador

A pesar que querer negarlo y hacer como si hubiera sido una pesadilla, sigo trabajando con PHP…

Tengo que hacerlo, pero algo que me he dado cuenta es que el desarrollar aplicaciones con Ruby on Rails (y programas/scripts pequeños en Ruby) ha cambiado mi forma de analizar y diseñar código en otros lenguajes.

En el caso de PHP, el código que ahora tengo que escribir es mucho más legible y organizado (dentro de los límites que permite PHP), porqué tan solo ver el horrible código que usualmente se hace con PHP trato de hacer lo posible para que no sea tan desagradable.

Un ejemplo muy claro es WordPress. A pesar de lo popular de la plataforma y de lo “estructurado” que según es, desarrollar un plugin o un tema ni se acerca a algo similar en Ruby. Basta con mirar el código de cualquier plugin o tema para darte cuenta de ello.

Hace poco leí un artículo sobre como el aprender diferentes lenguajes, aunque no los uses, mejora tus habilidades en los que si usas.

Ben Casnocha escribió en su libro My Startup Life, sobre la utilidad de acoplar el conocimiento común con experiencias no comunes. En este caso yo aplico como “común” lo que normalmente haces.

He leído también varios artículos sobre como tus diferentes hobbies te pueden ayudar en los negocios o tu trabajo. La programación no es la excepción.

Perdón por no dar más referencias, pero no las recuerdo ni las guardé :)

Next Page »