I18n e atribuição
|
|
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? |
|
|
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 |
|
|
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”. |
|
|
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 =(. |
|
|
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… |
|
|
Uai cara, eu tive um data assim, fiz Time.parse() |
|
|
mas dai ia ter que salvar como string a data, nao ia ficar ruim para relatorios, buscas e listagens? =). |
|
|
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. |
|
|
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: 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! |
|
|
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 =). |
|
|
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, |
|
|
Rapaz, eu gambiarrei total, fiz tipo a = Time.parse(data_errada.split(“/”).reverse) |
|
|
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, ficou muito bom! Fiz um fork do projeto, assim que puder dou uma olhada com mais calma =). Abraços |
|
|
Salve. Valeu, espero que te ajude :) Abraço, |


