Vi que se había liberado hace poco una nueva versión de Globalize, el plugin para Rails que permite tener traducciones de nuestros modelos, así que me animé a probarlo. Ahora es compatible con Rails 2.2 y hace uso de la nueva api para la internacionalización de nuestras aplicaciones. Además, ahora en lugar de tener una única tabla con todas las traducciones, hay que crear una tabla adicional para cada modelo con los campos que queramos que sean traducibles(tal como hace el plugin translate_columns de Samuel Lown). Por ahora hay que escribir la migración a mano, pero se planea hacer un generator para automatizar este paso(si saco un momentillo igual me animo a escribirlo yo, que nunca hice uno).
De momento parece que funciona bastante bien, salvo un detalle que me tuvo entretenido un buen rato y que comento por si alguien se encuentra en la misma situación.
En todos los ejemplos de la documentación aparece que podemos indicar la nueva locale usando un símbolo, pero resulta que si lo hacemos así, no se puede recuperar luego el campo traducido(aunque sí que se guarda correctamente en la base de datos) y lo que hay que hacer es utilizar cadenas en su lugar.
Supongamos que tenemos la clase Post con la siguiente migración:
# Post class Post < ActiveRecord::Base translates :title end
# CreatePosts
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.timestamps
end
create_table :post_translations, :force => true do |t|
t.references :post
t.string :locale
t.string :title
t.timestamps
end
end
def self.down
drop_table :post_translations
drop_table :posts
end
end
Podemos ver que si usamos un símbolo para nuestra locale, el campo nos devuelve un nil, pero si usamos una cadena, devuelve el valor correcto:
gambitero:rails-test dagi3d$ ./script/console Loading development environment (Rails 2.2.0) >> I18n.locale = :es => :es >> post = Post.new(:title => 'titulo') => #>> post.title => nil >> I18n.locale = "es" => "es" >> post.title = "titulo" => "titulo" >> post.title => "titulo" >> I18n.locale = "en" => "en" >> post.title = "title" => "title" >> I18n.locale = "es" => "es" >> post.title => "titulo"
También comentar que si tenemos traducido un campo en la locale por defecto(inicialmente ésta es 'en-US') e intentamos acceder a un atributo de una que todavía no tiene ningún valor asignado, se devolverá el valor de la locale por defecto. Si queremos evitar este comportamiento basta con comentar la línea 26 del fichero vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb para que no añada ésta a la lista de fallbacks(otra opción sería redefinir el constructor de la clase Globalize::Locale::FallBacks)
Por último decir que de momento la asociación que se crea entre nuestra clase y la generada por el plugin con las traducciones no se carga con 'eager loading' pero es una cosa que tienen prevista hacer.