Mostrando Artigos com 1 tag: Rails

Catucando no I18n do rails

Posted by joaolins, Fri Aug 08 18:48:00 UTC 2008

Depois de dar uma olhada no artigo do Carlos Brando e do Diego Carrion, resolvi dar uma catucada no I18n. Comecei com um exemplo simples citado nos blogs dos mesmos. Resolvi ir um pouco mais longe, usar o ActiveRecord e tentar internacionalizar mensagens pré-customizadas do rails e atributos das tabelas.

Bom, o resultado do meu arquivo de internacionalização foi esse:

Depois com seu arquivo de internacionalização pronto você pode criar um scaffold (scaffold é ótimo para exemplos/testes):
script/generate scaffold post title:string description:text author:string
Adicione algumas validações no model post:
class Post < ActiveRecord::Base
  validates_presence_of :title
  validates_length_of   :author, :within => 3..10
end

Depois de rodar os migrations acesse a URL de posts http://localhost:3000/posts/new tente criar um post sem digitar nada nos campos e veja todas as mensagens devidamente traduzidas.

Para traduzir os atributos da sua tabela/model você deverá usar algo como:
:human_attribute_names => { 
      :post => { 
        :title => "Título" 
      } 
}
Se você quizer ser mais especifico para uma determinada validação de um atributo você pode fazer isso da seguinte forma:
:active_record => {
  :error_messages => {
     :custom => { 
        :post => { 
          :title => { 
            :blank => "erro especifico para título em branco no post" 
        }
      }
    }
 }
}
#observe que isso tem que ser feito dentro do 
#contexto do active_record.error_messages

Nota: Para minha surpresa acabei descobrindo um bug que acontece quando você não especifica mensagens default para o ActiveRecord no seu arquivo de localização. O que acontece é que o método full_messages do ActiveRecord procura por mensagens padrões para os validations e quando não encontra a chave, ele retorna um Array ao invés de uma String, por consequência o error_messages_for usa o full_messages esperando dele uma mensagem string, mas recebe esse bendito Array que não deveria ter sido retornado e ao concatenar a string com o Array dá pau. O erro na minha opinião é bem bobo mais é uma coisa que deve ser tratada…

Mais informações sobre I18n: http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api

2 comments | Filed Under: | Tags: Railsrails

2º ESOL - Palestra: Ruby on Rails colocando a web nos trilhos

Posted by joaolins, Sat Jul 05 13:56:00 UTC 2008

Essa semana participei do II ESOL que aconteceu no CEFET-PE. Foi a minha primeira paticipação em um evento de software livre. Tentei passar um pouco do mundo Ruby e Rails com o intuito de consquistar alguns adeptos e fortalecer a nossa comunidade local. A palestra foi nos moldes do DHH. Fiz uma breve introdução ao Ruby e um hands on com Rails para mostrar as facilidades de utilizar o framework.

O evento estava muito bom e só tenho a agradecer ao pessoal da organização pelo apoio e atenção que me deram durante todo tempo que estive por lá.

O código da aplicação para quem quizer brincar.

0 comments | Filed Under: | Tags: Railsrails

encontrando uma sarna para se coçar

Posted by joaolins, Tue Dec 18 19:36:00 UTC 2007

Muita gente se beneficia de software open source e ferramentas livres. Quando isso acaba se tornando constante pode acabar batendo aquele sentimento de que é necessário dar alguma coisa em troca, contribuir. É ruim pensar que existem pessoas trabalhando por trás daquilo e você está simplesmente mamando. Isso certamente não passa pela cabeça de todo mundo, mas provavelmente da maioria dos mineradores.

Bom, eu vou contar a história que aconteceu comigo.

Tudo começou quando tive um pequeno problema com um sistema que estou fazendo com Rails. Lá é preciso fazer upload de um arquivo XML em um dado momento. Até ai tudo bem:

result = xml_parser.parser(params[:file_upload])

Isso funcionou bem. Todos os testes passaram e eu nem me preocupava com o tipo de objeto que vinha dentro do params[:file_upload], tinha em mente que sempre seria um TempFile.

Qual não foi minha surpresa quanto foi feito o deploy em produção: BOMBA! Acabei descobrindo que, nas versões de Ruby anteriores à 1.8.6, somos obrigados a chamar open no TempFile.

result = xml_parser.parser(params[:file_upload].open)

Aparentemente é uma modificação bem pequena. Desta vez a surpresa foi um pouco menor, já que aconteceu em ambiente de testes. Mas não pude deixar de me assustar quando um erro saltou na minha cara:

NoMethodError: private method `open' called for #<StringIO:0xb7c35020>

Depois da mão na cabeça, veio naturalmente um pouco de depuração e inspeção. Notei que o params[:file_upload] estava retornando um StringIO e que a chamada ao método open, que na documentação do ruby core aparece como publico e na verdade é privado, dava o erro acima. Resolvi tirar a história a limpo. Dei uma lida no código do Rails e acabei descobrindo que se o upload for de arquivos menores do que 10KB um StringIO é retornado e não um TempFile como eu esperava.

Neste ponto eu já sabia a razão de todos os meus problemas e só faltava resolver, o que fiz foi o seguinte:

if params[:upload_file].instance_of?(StringIO)
    result = xml_parser.parser(params[:upload_file])
else
    result = xml_parser.parser(params[:upload_file].open)
end

Isso funciona para todas as versões de Ruby e tamanhos de arquivo, mas eu não fiquei satisfeito com a solução porque não a achava limpa o bastante e porque esse comportamento do Rails não era documentado.

Meu código estava funcionando, mas eu não estava satisfeito. Lembra da história de contribuir e parar de mamar? Pensei: “é hora de largar a teta!” Eu estava disposto e há algum tempo já vinha procurando sarna para me coçar, foi só procurar um pouco na internet para saber o que eu precisava fazer para contribuir com o Rails. Encontrei os slides encorajadores de Josh Susser e arregacei as mangas para por as mãos à obra.

Depois de ter lido o código, eu sabia exatamente como resolver o problema. Escrevi um email para a rails-core falando do problema e fazendo uma proposta para que o Rails retornasse apenas TempFile, ao invés de tentar fazer uma otimização que pode fazer muita gente ter que coçar a cabeça para resolver . Alguns emails rolaram na lista e o primeiro a me responder foi o Michael Koziarski que escreve para o The Rails Way.

Koz achou a minha proposta interessante, mas ele não conseguiu entender que tipo de bug aquela otimização poderia resolver. Enviei uma resposta e tentei explicar tudo de forma mais detalhada em outro email para a lista. Foi quando Jonathan Yurek me respondeu que todos os meus problemas poderiam ser solucionados de uma forma bem simples usando o poder libertador do duck typing:

result = xml_parser.parser(params[:upload_file].read)

A solução proposta pelo Yurek funciona perfeitamente. Eu não tinha prestado atenção, mas o método read que funciona no StringIO, também pode ser usado para o TempFile, pois ele é um Delegate de File que herda de IO e possui o método read.

Depois disso Koz respondeu que ainda acharia interessante que isso fosse documentado em algum lugar da API do Rails e que ele poderia aplicar a modificação caso alguém fizesse o patch. Hongli Lai também escreveu para a lista informando sobre um post que fez em seu blog ao ter um problema bem parecido com o que eu tive e pareceu solidário a minha proposta.

Ainda não mandei o patch para deixar claro o comportamento do Rails ao fazer uploads. Explicar esse comportamento não é difícil. Na verdade o maior problema é saber exatamente o melhor local para colocar a informação. Alguma sugestão?

1 comment | Filed Under: | Tags: Railsrails