JavaFree.org | RubyOnBr.org

I18n e atribuição

Acompanhar I18n e atribuição 16 posts, 4 participantes

Avatar Fernando Luizão 1863 posts

Pessoal, estou com uma dúvida em relação à atribuição de valores com I18n. Por exemplo, as datas estão configuradas da seguinte forma:

Ok, até aí tudo bem, ele formata a data normalmente. O que eu não estou sabendo fazer (e também não achei ninguém falando sobre isso) é como atribuir um valor localizado para um objeto do active record. Em um formulário, a data será enviada no formato “%d/%m/%Y”, mas o AR não atribui o valor corretamente (fica nulo). Por exemplo:

O que fazer nesse caso? Sobrescrever o setter é uma boa saída? E se houverem outras localizações?

 
Avatar Rafael Cruz Rubert 668 posts

não entedi, você quer que fique no banco : “%d/%m/%Y?

Se for para tratar acho que um before_validate deve resolver com um self.data ou coisa assim

 
Avatar Fernando Luizão 1863 posts

Não… eu quero uma conversão instantânea =). O usuário vai colocar a data no formato “%d/%m/%Y” no formulário, se ele for brasileiro. Se for um americano, vai colocar a data como “%m/%d/%Y”. Quero que a atribuição no model seja transparente, independente do formato que o cara digitar, no banco a data vai ser gravada no formato correto “%Y-%m-%d”.

 
Avatar Rafael Cruz Rubert 668 posts

Agora sim entendo mas esse tratamento não seria em um nivel da view? porque assim vai ficar transparente para o usuario, e no banco salva no melhor modo que o banco trabalha, no postgreSQL se voce tenta salvar “01/01/2009” ele vai salvar “2009-02-01” pode usar o params[:locale] para na hora do cadastro mostrar o devido input. =) mas no model nem imagino o que fazer, so se no caso tivesse um campo data_en e data_br mas dai ficaria muita gambiarra =(.

 
Avatar Fernando Luizão 1863 posts

Então, é isso que eu não quero fazer… mas to achando difícil fazer essa conversão, mesmo no controller… estranho é que não acho ninguém fazendo isso…

 
Avatar nofxx 1960 posts

Uai cara, eu tive um data assim, fiz Time.parse()

 
Avatar Rafael Cruz Rubert 668 posts

mas dai ia ter que salvar como string a data, nao ia ficar ruim para relatorios, buscas e listagens? =).

 
Avatar Fernando Luizão 1863 posts

nofxx, se vc tentar fazer:

Vai dar uma exceção, porque ele vai admitir a data no formato mm/dd/yyy e não dd/mm/yyyy. Se o parse aceitasse um formato ou coisa do tipo acho que rolaria… mas até agora não vi nada.

 
Avatar Rafael Rosa Fu 112 posts

Salve,

Até onde eu sei não há um método simples para fazer isso, o I18n só possui métodos para converter datas em strings formatadas e não o inverso. Além disso, quando você faz uma attribuição do tipo:

Você está chamando um método da classe Date, que nem sabe da existência do I18n, uma vez que ele é um módulo do Rails e não do Ruby. Porém eu encontrei uma forma de fazer exatamente o que você quer, obviamente é um hack, mas pode ser interessante, se você realmente precisa disso pode te ajudar, e foi divertido escrevê-lo :)

Parece muito código para pouca coisa mas é necessário. Basicamente adicionamos um novo método ao I18n para fazer o parse de strings para o formato data, mas para isso precisamos de um método para encontrar as chaves de tradução, que não existe no I18n::Backend::Simple, então o criamos. Assim, você pode utilizá-lo em outros lugares como no exemplo abaixo:

A segunda parte do código captura o parse interno original da classe Date e o encapsula numa chamada que verifica se ele obteve sucesso ou não. Se não funcionar ele tenta executar o parse do I18n, e dá para fazer coisas como:

Note que esse hack é bastante frágil, ele funciona bem com o I18n com simple backend, se estiver usando outro pode dar problema. Só para constar fiz os testes rodando Rails 2.2.2 que vêm com o i18n-0.0.1. Eu o coloquei no meu diretório lib, e adicionei um arquivo com

require ‘i18n_extensions’
no diretório config/initializers.

A escolha das chaves de tradução (:date, :formats, :default) é básica, só para dar uma idéia. Se você mudá-las tome cuidado para que as chaves escolhidas existam em todas as traduções disponíveis, durante meus testes eu notei que a não se pode contar com a equivalência delas, cada localização é uma história diferente.

Quanto ao formato gravado no banco, até onde sei e testei, se o campo no modelo for um objeto Date e o campo no banco de dados for um tipo DateTime da vida, o Rails se vira para gravar no formato correto. Se você precisar gravar essa data num campo string com o formato do local, basta chamar o localize:

Espero ter ajudado em alguma coisa, estou à disposição para conversar.

Até mais,
Rafael
www.rafaelrosafu.com

 
Avatar Fernando Luizão 1863 posts

Rafael:

S-E-N-S-A-C-I-O-N-A-L

Funcionou direitinho, era isso que eu queria, um parse localizado =). Vou fazer um pra traduzir numeros localizados também =).

Valeu pelo código!

 
Avatar Fernando Luizão 1863 posts

Adicionei suporte ao parseamento de números. Código:

Que tal a gente criar um plugin com isso? Suporte a outros backends de i18n, sei lá… acho que será muito útil =).

 
Avatar Rafael Rosa Fu 112 posts

Salve,

Bacana, podemos tentar sim. O maior problema é que algumas partes do código dependem de coisas que não estão na interface básica do Backend, vou até pesquisar na lista do I18n e mandar uma sugestão para que eles liberarem o acesso, pelo menos de leitura, ao @translations, ou liberem a pesquisa direta. Valeu por adicionar mais coisas, vamos conversando.

Até mais,
Rafael
www.rafaelrosafu.com

 
Avatar nofxx 1960 posts

Rapaz, eu gambiarrei total, fiz tipo

a = Time.parse(data_errada.split(“/”).reverse)

 
Avatar Rafael Rosa Fu 112 posts

Salve,

Seguindo a idéia do Fernando Luizão, eu peguei o código, refatorei acertei algumas coisinhas e fiz um plugin/gem. Está publicado no GitHub, o link é:

http://github.com/rafaelrosafu/i18n_localize_core/tree/master

Testei como plugin, funciona que é uma beleza. A gem ainda não testei, eles ainda não colocaram no servidor de gems. Espero escrever um post sobre o processo no meu blog em breve, mas deixei um readme decente.

Até mais,
Rafael
www.rafaelrosafu.com

 
Avatar Fernando Luizão 1863 posts

Rafael, ficou muito bom! Fiz um fork do projeto, assim que puder dou uma olhada com mais calma =).

Abraços

 
Avatar Rafael Rosa Fu 112 posts

Salve.

Valeu, espero que te ajude :)

Abraço,
Rafael
www.rafaelrosafu.com