Cristão. Este é um bug no Rails que verifica o banco de dados para inferir o tipo necessário para os atributos multiparâmetros. Meu palpite é que seu atributo "date_time" não está associado a uma coluna de tempo em seu banco de dados.
Recentemente, abordei esse problema em que queria um atributo não banco de dados para atributos multiparâmetros aceitos, essa foi a melhor solução que pude encontrar:
Eu me peguei querendo definir um
attr_accessor
para lidar com a passagem de uma data para o meu modelo em um form_for
tag com o f.datetime_select
ajudante. Então isso é o que eu tinha:Modelo:
attr_accessor :my_time
Visão:
<%= f.datetime_select :my_time %>
Infelizmente, quando envio meu formulário, recebo isso:
1 error(s) on assignment of multiparameter attributes
Bem, acontece que este é realmente um bug do Rails, um ticket para o qual foi enviado. Enquanto isso, como vamos fazer isso funcionar? A única solução que encontrei que era remotamente atraente foi usar
composed_of
como um substituto para attr_accessor
. assim... Modelo:
composed_of :my_time,
:class_name => 'Time',
:mapping => %w(Time to_s),
:constructor => Proc.new{ |item| item },
:converter => Proc.new{ |item| item }
Não sei quase nada sobre o
composed_of
então você provavelmente deve fazer sua própria leitura nele, mas o que eu sei é que ele cria um leitor e um gravador para a variável de instância fornecida e, mais importante, o setter aceita atributos multiparâmetros. Como escolhi as opções:class_name:o nome da nossa classe esperada. Neste caso,
Time
mapeamento:o primeiro argumento é a classe e o segundo argumento parece funcionar com qualquer método ao qual uma instância da classe responda. Eu escolhi
to_s
construtor:Não tenho certeza de como isso deve funcionar. Parece ser chamado quando @my_time
é nil
.conversor:Não tenho certeza de como isso deve funcionar. Parece ser chamado quando from my_time=, mas não parece ser aplicado com atribuição em massa. Um problema que encontrei com esta solução foi que os tempos estavam sendo definidos em UTC em vez do fuso horário do ambiente. Então, infelizmente, não podemos usar my_time diretamente, mas precisamos convertê-lo para o fuso horário adequado:
Time.zone.parse(my_time.to_s(:number))