O problema
Passei um bom tempo ontem tentando trabalhar com localização numa aplicação Rails 2.1 na qual estou trabalhando. Na verdade o que eu queria fazer era manter todas as mensagens da minha aplicação (que não é muito grande) num arquivo e chamar as mensagens dentro dele desde a view. Preferi utilizar uma solução de L10n porque ia resolver meu problema e ia me outorgar soluções a uns possíveis problemas que poderia ter no futuro, como utilizar a ferramenta em diversas linguagens.
Pesquisei sobre L10n em Rails mas somente achei soluções para Rails 1.2. Na pagina de plugins do Rails existem diretórios para diferentes plugins, mas os links não estão funcionando agora. Felizmente cheguei nuns posts que falavam sobre L18n em Rails com JRuby e assim apos bater cabeça um pouco, consegui solucionar meu problema.
A solução
Antes de implementar e demostrar a solução começarei criando uma aplicação Rails 2.1 de teste:
jruby -S rails teste
Como o arquivo de mensagens ira ser carregado pelo método java.util.ResourceBundle.getBundle, o arquivo devera estar no classpath do Java. O arquivo de mensagens estará localizado na pasta app/views do nosso projeto Rails e por tal motivo criaremos um script que ira incluir a pasta no classpath e seguidamente inicializar o servidor. O script esta dentro da pasta raiz do nosso projeto; chamarei ele de start_server:
export CLASSPATH="app/views:$CLASSPATH" jruby script/server
Para executar o script executamos:
./start_server
e possivelmente obteremos um output similar a esse:
=> Booting WEBrick... JRuby limited openssl loaded. gem install jruby-openssl for full support. http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL => Rails 2.1.0 application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2008-07-03 13:36:37] INFO WEBrick 1.3.1 [2008-07-03 13:36:37] INFO ruby 1.8.6 (2008-07-02) [java] [2008-07-03 13:36:37] INFO WEBrick::HTTPServer#start: pid=21025 port=3000
Criaremos um arquivo chamado messages_pt_BR.properties na pasta app/views do nosso projeto. O arquivo, como já sabemos, ira conter as mensagens da nossa aplicação para o idioma português e o maravilhoso pais Brasil, no seguinte formato:
chave=valor app.title=MouseOver Studio
Criaremos agora a implementação. Para isso iremos gerar um controller chamado Localizacao:
jruby script/generate controller Localizacao index
Nossa logica estará no arquivo app/controller/application.controler, de modo que podamos injetar uma variável com as mensagens de nossa aplicação em todos os controllers. O arquivo devera ficar algo assim:
require "java"
class LocalizacaoController < ActionController::Base
...
before_filter :localizate
def localizate
locale = java.util.Locale.new("pt", "BR")
@messages = java.util.ResourceBundle.getBundle("messages", locale)
end
...
end
Basicamente o que fizemos foi incluir as bibliotecas do Java com require ‘java’, criar um filtro chamado localizate e nele definir a variável messages que contem as mensagens indicadas. No exemplo eu coloquei pt e BR estaticamente, mas isso poderia vir da base de dados ou de algum arquivo de configuração.
Vou modificar agora a view, vou apagar o conteúdo do arquivo app/views/localizacao/index.html.erb e colocar um texto besta, somente para testar:
< %= @messages.get_string "app.title" %>
Tudo pronto, vamos agora testar a aplicação. Não se esqueçam que o servidor tem que ser inicializado com o script que criamos porque o Java precisa carregar o arquivo de mensagens.
Testamos nossa aplicação acessando http://localhost:3000/localizacao e o resultado é:
O bonus
MissingSourceFile in LocalizacaoController#index no such file to load -- sqlite3
Opa! O que aconteceu? Rails trabalha por padrão com bancos de dados e a não temos nenhuma base configurada, e não queremos configurar nenhuma, queremos trabalhar com Rails sem depender de um banco de dados. Possivelmente já leram em outros blogs que a solução a esse problema é adicionar a seguinte linha no arquivo config/environment.rb:
config.frameworks -= [ :active_record ]
mas em Rails 2.1 se reiniciarmos o servidor apos a alteração iremos obter o seguinte erro:
/Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:278:in `load_missing_constant': uninitialized constant ActiveRecord (NameError) from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:467:in `const_missing' from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:479:in `const_missing' from /Users/jesper/Projects/rails/test_new_rails_features/config/initializers/new_rails_defaults.rb:5 from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load' from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load' from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in' from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load' from /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/initializer.rb:475:in `load_application_initializers' ... 32 levels... from /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/commands/server.rb:39 from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `gem_original_require' from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `require' from script/server:3
Ja foi criado um ticket para esse erro e o mesmo foi corregido por DHH. A solução consiste em alterar o arquivo config/initializers/new_rails_defaults.rb com esse código aqui, o qual vai vir como parte do Rails 3.
Reiniciamos nossa aplicação, fazemos o teste de novo e agora sim o resultado é:
MouseOver Studio
É nois! Qualquer duvida não se esqueçam de perguntar que eu responderei rapidamente e muito contente. Agora irei continuar meus estudos com Rails, falo!
7 respostas ate agora ↓
1 Leandro // Jul 14, 2008 at 4:19 pm
Eeee JRuby que é uma mão-na-roda pra nos ajudar!
Ótimo post!
2 Diego Carrion // Jul 14, 2008 at 4:48 pm
Obrigado Leandro!
legal conhecer mais pessoas mexendo com JRuby
3 Jimmy // Jul 17, 2008 at 6:37 pm
Ótimo post.
Só acho que o blog deveria ser atualizado com mais frequência, desde que sai de sampa esse continua sendo o ultimo post.
Pow toma vergonha na cara e agiliza rapáááá…
Uma sugestão seria falar sobre “Rails CMS” e qual entre tantos é o mais legal para se usar ou qual atende determinadas necessidades, segue um primeiro passo: http://www.infoq.com/news/rails-cms-plugins
[]s
4 Diego Carrion // Jul 17, 2008 at 10:49 pm
Hahahahah cade o link para teu blog no teu nome, ta demorando!
Ja ta saindo um post quentinho sobre o SproutCore, se tudo der certo sai hoje mesmo
Valeu pelo comentário e volta logo que o povo ta com saudades (:
5 Leandro // Aug 15, 2008 at 9:44 am
Eu quero o melhor dos dois mundos!!! rsrsrs
Que mais você tem feito com JRuby?
6 Paulo Henrique // Jan 26, 2009 at 12:17 pm
Obrigado pelo Post, estava tentando tirar o activerecord do rails e tava dando Pau…. vlw
7 Diego Carrion // Jan 26, 2009 at 1:03 pm
De nada Paulo, volte sempre (:
Deixar um comentário