У меня есть date_select внутри формы, однако при отправке возвращаемое значение находится в хэш-форме, например, так:
{"(1i)"=>"2010", "(2i)"=>"8", "(3i)"=>"16"}
как я могу преобразовать это в формат Date в рельсах, чтобы я мог использовать его как условие при запросе базы данных, например: : условие => {: даты ==: some_date_from_date_select}
? я попытался вызвать Date.parse (: some_date_from_date_select)
, но это не сработало, потому что ожидал строку, а не хэш-карту.
Есть ли способ сделать это с помощью рельсов?
спасибо
Я не знаю насчет рельсов, но этот «однострочный» трюк помогает:
irb(main):036:0> d = Date.parse( {"(1i)"=>"2010", "(2i)"=>"8", "(3i)"=>"16"}.to_a.sort.collect{|c| c[1]}.join("-") )
=> #<Date: 4910849/2,0,2299161>
irb(main):037:0> d.to_s
=> "2010-08-16"
Или, с меньшим количеством магии:
h={"(1i)"=>"2010", "(2i)"=>"8", "(3i)"=>"16"}
d=Date.new(h['(1i)'].to_i, h['(2i)'].to_i, h['(3i)'].to_i)
d.to_s
=> "2010-08-16"
Этот конкретный код (тот, который выполняет преобразование) можно отследить в lib/active_record/connection_adapters/abstract/schema_definitions.rb
, строка № 67 и далее, т.е. метод type_cast
.
Эти два метода используются для генерации даты из строки:
def fast_string_to_date(string)
if string =~ Format::ISO_DATE
new_date $1.to_i, $2.to_i, $3.to_i
end
end
# Doesn't handle time zones.
def fast_string_to_time(string)
if string =~ Format::ISO_DATETIME
microsec = ($7.to_f * 1_000_000).to_i
new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
end
end
# Note that ISO_DATE is:
ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/