Rails, REST e i18n
Publicado por el Miércoles, 30 de Abril de 2008
Ahora que estamos utilizando a tope Rails 2.0 y toda la parafernalia REST en nuestras aplicaciones, nos hemos dado de bruces con un pequeño problema de rutas.
La solución pre-REST
Digamos que nuestras aplicaciones están internacionalizadas y que tenemos la costumbre de poner el código de idioma en la URL, utilizando un filtro para forzar que este código aparezca en la misma mediante una redirección. Una técnica bastante habitual y extensamente documentada.
# application.rb
before_filter :set_language
def set_language
unless (locale = params[:locale]).blank? && Languages.supported?(locale)
set_locale(@locale = locale)
else
redirect_to params.merge(:locale => Languages.default)
return false
end
end
# routes.rb
map.connect ':locale/:controller/:action/:id'
map.connect ':controller/:action/:id'
De este modo, la primera petición a la aplicación que no lleve el idioma en la URL recibirá como respuesta una redirección a la misma URL con el añadido del idioma.
El problema con REST
Si añadimos un recurso, las rutas generadas y los helpers para crear paths y urls no incluirán el código de idioma, por lo tanto, si no hacemos nada, al pasar por el filtro cada petición recibirá como respuesta un redirect. Mal asunto.
# routes.rb ActionController::Routing::Routes.draw do |map| map.resources :customers end
La solución
En primer lugar necesitamos modificar ligeramente las rutas para que estas incluyan el código de idioma.
ActionController::Routing::Routes.draw do |map|
map.with_options(:path_prefix => ':locale') do |localized_map|
localized_map.resources :order
end
end
Por último debemos lidiar con la generación de rutas. Como quedaría feo (y no muy DRY) tener que andar pasando el código de idioma a cada helper (léase order_path(@current_locale, @order)) lo que necesitamos es modificar el comportamiento de Rails para que lo haga él solito. Y qué suerte la nuestra, ya existe un plugin para eso: localize_url_helpers, que de forma transparente incluye el idioma y nos permite usar los helpers como de costumbre.
C’est voila.
Kilos y kilos de refactoring
Publicado por el Martes, 29 de Abril de 2008
Las últimas semanas de desarrollo con Ruby on Rails en Trabe Soluciones se han dividido a partes iguales entre el desarrollo de una nueva aplicación y la modificación y mejora de otras dos. Trabajar con código antiguo (entiéndase por antiguo: con al menos un mes de vida) es siempre una invitación para la mejora y el refactoring. Es indiscutible que a lo largo de un mes un programador evoluciona de manera tal que todo lo que ha hecho hasta el momento le parece malo (o al menos peor que lo que hace actualmente). Demos paso al refactoring.
Podemos enfocar esta tarea de un modo sistemático y enfermizo, en busca de un código excelso cuya sola contemplación nos haga entrar en una suerte de experiencia mística (perdiendo tiempo y salud mental) o bien podemos dejar que fluya sin más.
Un ejemplo: vamos a simplificar la definición de las típicas acciones index que sólo delegan. Cuando te encuentras por segunda o tercera vez con algo como esto:
def index list render :action => list end
... decides cambiarlo por algo como …
index_as :list
# Refactoring ohh yeah!!!
def self.index_as(method)
define_method :index do
send(method)
render :action => method
end
end
10 minutos después la aplicación ha perdido peso y todos lo agradecemos (y más ahora que llega el verano y la playa).
Parece poca cosa, pero cualquier refactoring, por pequeño que sea, es bueno. El principio de no repetirse no es una idea feliz de un loco cualquiera; es un concepto fundamental en el desarrollo de aplicaciones de calidad, y si aún no lo practicas ya es momento de empezar.
Conclusiones tras el seminario introductorio de Ruby on Rails
Publicado por el Jueves, 24 de Abril de 2008
Ya ha terminado el seminario (bueno, hace un par de horas) y estamos muy satisfechos con el resultado final. La gente ha participado, parece que no se ha aburrido (demasiado) y han aguantado como campeones las casi cuatro horas de Ruby y Rails. Tanto Asís como yo y el resto de gente en Trabe Soluciones queremos agradecer a todo el mundo su asistencia. También queremos darles las gracias a Fernando Bellas y Víctor Carneiro por su ayuda y colaboración para montar el seminario.
Por cierto, ya hemos dejado para descargar las trasparencias en PDF de la charla.
Nos vemos en la próxima.
Jugando con JRuby
Publicado por el Lunes, 21 de Abril de 2008
Asís y yo hemos decidido hablar un poco sobre JRuby en el seminario introductorio de Rails del jueves, ya que esperamos que la mayoría de los asistententes vengan del mundo Java.
Para preparar el material he vuelto a revisitar la página del proyecto que tenía un poco abandonada. Me ha sorprendido lo mucho que han avanzado y como han mejorado la integración con Java. Es bastante sencillo:
include Java
import 'java.util.ArrayList'
list = ArrayList.new
list.add "uno"
list.add "dos"
list.add "tres"
list.each do |n|
puts "num: #{n}"
end
list.class.name # => "Java::JavaUtil::ArrayList
list.java_class.name # => "java.util.ArrayList"
Esto y mucho más, en el wiki. La verdad, crear ventanas swing desde jirb hace que un escalofrio te recorra toda la espalda. Curioso cuanto menos.
NOTA: Un día de estos pruebo a desplegar alguna de nuestras aplicaciones con JRuby en un Tomcat utilizando Goldspike y os cuento.
delegate_method versión 2
Publicado por el Jueves, 17 de Abril de 2008
Hace tiempo propusimos desde este blog el método Module::delegate_method como sustituto del método delegate de Rails.
El tiempo ha pasado y después de usarlo mucho hemos decidido simplificarlo, cambiar su sintaxis y, como entonces, ponerlo a disposición de todo el que lo quiera usar.
class Module
#
# delegate_method :do_something,
# :to => :other_object
#
# delegate_method :do_other_thing,
# :to => :another_object,
# :as => :do_something,
# :default => "Can't do it"
#
def delegate_method(method, options)
to = options[:to]
as = options[:as] || method
default = options[:default]
raise ArgumentError(':to param is mandatory') if to.blank?
module_eval %{
def #{method}(*args, &block)
#{to}.__send__(:#{as}, *args, &block) || #{default.inspect}
end
}
end
end
Soporte de TimeZones en Rails 2.1... ¡Por fin!
Publicado por el Lunes, 14 de Abril de 2008
Mmmm, adoro el sabor de las buenas noticias. En Rails 2.1, habrá soporte para timezones. No es todo lo que me gustaría ver en Rails acerca de internacionalización, pero es algo. Ya existe un pequeño tutorial sobre el uso del soporte en nuestras aplicaciones, que además explica como migrar si vuestra aplicación usa la clásica combinación tzinfo + tzinfo_timezone.
¿Quieres trabajar en Trabe Soluciones?
Publicado por el Sábado, 12 de Abril de 2008
Trabe Soluciones está creciendo. Ahora que nos vamos a mudar a unas oficinas más amplias tenemos una vacante. La oferta de trabajo que estamos distribuyendo es la siguiente.
Buscamos personas para trabajar en A Coruña.Trabe te necesita
Nos gustaría que supieses desarrollar aplicaciones web MVC con J2EE y Ruby on Rails, que controlases de HTML, CSS y Javascript, que tuvieses conocimientos de diseño gráfico, que administrases servidores, que te sintieses cómodo en Linux, que te gustase usar software libre,...
Si esto te describe ven corriendo. En caso contrario, no te preocupes, valoramos la experiencia que tengas, pero también nos interesa tu pasión y tus ganas de aprender, de trabajar de una manera diferente, de asumir responsabilidades y de crecer con nosotros.
Te ofrecemos unas excelentes condiciones. Todo lo que te ofrecen el resto de ofertas de trabajo y mucho más: horario flexible, oficina céntrica(nada de polígonos), plantilla joven, café a media manaña, no llevamos corbata ni traje... Nos importa tu calidad de vida.
Si quieres saber más de nosotros, puedes echar un vistazo a nuestra web (http://www.trabesoluciones.com) o a nuestro blog (http://4trabes.com), o directamente contactar con nosotros para plantearnos cualquier duda (contacto@trabesoluciones.com).
Esperamos tu curriculum en rrhh@trabesoluciones.com.
Ya han llegado los primeros CVs. ¿A qué esperáis para enviar el vuestro?
Faltan 15 días para el Seminario de Ruby on Rails en la FIC
Publicado por el Jueves, 10 de Abril de 2008
Os recuerdo que el próximo día 24 de Abril impartimo el seminario de Ruby on Rails en la Facultad de Informática de A coruña. Los interesados pueden acercarse al aula 3.4 a las 16:00 de la tarde.
Os puedo adelantar que tendrá dos partes: un breve curso de choque sobre Ruby (utilizando trozos de código) y una introducción al framework Rails a través de un ejemplo de aplicación.
Nos vemos el 24.
Google Chart API + ruby = gchartrb
Publicado por el Martes, 01 de Abril de 2008
En nuestro último proyecto necesitamos incluir varios tipos de gráficas (líneas, barras y alguna tarta). De entre las múltiples posibilidades existentes hemos decidido usar el API de gráficas de Google (Google Chart API) que nos ofrece un montón de posibiliades de manera sencilla, fiable, gratuita e ilimitada. La única peculiaridad de su uso es que los datos a representar deben ser codificados antes de enviarlos al servidor de gráficas. Esto no representa mayor problema, menos aún cuando existen varios wrappers distribuidos como gemas o plugins que hacen este trabajo por nosotros, como son: gchartrb, Googlecharts o Google Charts on Rails.
Nosotros estamos usando gchartrb, porque entendemos es la más completa y documentada y porque su API nos agrada más. Por ejemplo, para pintar una sencilla gráfica como la que sigue…
... necesitamos un código como este:
PIE_COLORS = %w(9bd500 a4d520 b0d54b bbd575 c7d5a0)
data = Post.count(:group => :user_name, :order => 'count_all desc')
pie_chart = GoogleChart::PieChart.new('300x100') do |chart|
data.each_with_index do |row, i|
chart.data "#{row[0]} (#{row[1]})", row[1], PIE_COLORS[i]
end
end
image_tag pie_chart.to_url
