Problemas com form_for ao Sobrescrever Atributos do ActiveRecord
update 15-12-2009: Uma excelente forma de evitar a re-implementação dos accessors criados pelo Rails é através do plugin delocalize, que tira proveito do arquivo yaml de localização. Para saber mais sobre este plugin acesse: http://github.com/clemens/delocalize
Esta semana precisei utilizar campos de data em model onde deveria ser guardado no DB (mysql) como date mas no meu aplicativo rails deveria ser exibido no formato brasileiro.
Como estou no Rails 2.2 nada mais simples que usar o método localize para resolver isso… bastava sobrescrever os atributos do ActiveRecord e formatar o campo em seu getter e setter. Algo como abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Service < ActiveRecord::Base def end_date=(date) date = date.to_date if date.present? write_attribute(:end_date,date) end def end_date date = read_attribute(:end_date) I18n.localize(date) if date.present? end end |
No setter ( end_date= ) estou pegando valor no formato brasileiro e convertando para um objeto data através do método to_date do BrazillianRails e depois usando o método write_attribute para inserir este valor em end_date .
No getter, a única coisa seria ler o atributo através do read_attribute e então usar o localizer para alterar seu valor.
Isso irá funcionar em todos os lugares, exceto dentro de um text_field ou outros campos como text_area. Ao tentar acessar uma action edit seus campos estarão preenchidos com 2008-12-10 ao invés de 10/12/2008 .
Aí que está a confusão. O método text_field utiliza outro método para trazer seu valor, o value_before_type_cast … Este método avalia se seu atributo possui alguma implementação tipo atributo_before_type_cast e todos os atributos padrão de seu model ActiveRecord terão um before_type_cast e este método será chamado ao invés do getter que implementamos acima.
Não estou certo porque o Rails assume este comportamente, mas acredito que seja por causa de campos como números ou outros campos que seriam problemáticos para serem escritos em um campo de texto.
Mas para solucionar isto podemos agir de várias formas, alterando o Rails através de algo na pasta lib, através de um plugin… mas na minha opnião a forma mais simples que consegui pensar foi através de um alias. Veja abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Service < ActiveRecord::Base def end_date=(date) date = date.to_date if date.present? write_attribute(:end_date,date) end def end_date date = read_attribute(:end_date) I18n.localize(date) if date.present? end alias_method :end_date_before_type_cast, :end_date end |
Espero ajudar alguem que passar pela a mesma situação, não precisando cavar dentro do código do Rails para entender o que acontece. Se alguem souber de outra forma mais elegante, por favor comente abaixo.
UPDATE 15-12-2009: Uma excelente forma de evitar a re-implementação dos accessors criados pelo Rails é através do plugin delocalize, que tira proveito do arquivo yaml de localização. Para saber mais sobre este plugin acesse: http://github.com/clemens/delocalize
Comentário
CATEGORIAS
HomeDesign
SEO
Empreendimento
Cifras
Ruby e Rails
Flex
Photoshop
Flash
XHTML/CSS
JavaScript
Variados
Database
Firefox
Projetos
3D
Projetos
TextMate
Smalltalk
Mac
Livros
ARQUIVO
07/2010 (2)06/2010 (4)
05/2010 (4)
04/2010 (4)
03/2010 (5)
02/2010 (7)
01/2009 (4)
12/2009 (7)
11/2009 (4)
10/2009 (10)
09/2009 (7)
08/2009 (6)
07/2009 (12)
06/2009 (5)
05/2009 (6)
04/2009 (9)
03/2009 (14)
02/2009 (18)
01/2009 (14)
12/2008 (20)
11/2008 (18)
10/2008 (9)
09/2008 (12)
08/2008 (6)
07/2008 (12)
06/2008 (10)
05/2008 (15)
04/2008 (19)




PomoDo e Pomodoro Technique
comentado por Luis
Flash SlideShow
comentado por Gilmar
50% do software é design
comentado por Daniel Lopes
Vetores Grátis - VectorLab Pack
comentado por louis vuitton
Texturas legais
comentado por thomas sabo kommt