Как преобразовать хэш-значение, возвращаемое из date_select в рельсах в объект Date? - PullRequest
8 голосов
/ 17 августа 2010

У меня есть date_select в моем виде внутри формы, однако при отправке возвращаемое значение находится в хэш-форме примерно так:

{"(1i)"=>"2010", "(2i)"=>"8", "(3i)"=>"16"}

как я могу преобразовать это в формат даты в рельсахя могу использовать его в качестве условия при запросе базы данных, например :condition => {:dates == :some_date_from_date_select}?я попытался вызвать Date.parse(:some_date_from_date_select), но это не сработало, потому что ожидал строку, а не хэш-карту.

есть ли способ рельсов сделать это?

спасибо

Ответы [ 5 ]

9 голосов
/ 17 августа 2010

Я не знаю о пути рельсов, но этот "однострочный" делает свое дело:

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"
2 голосов
/ 15 февраля 2013

У меня есть короткое однострочное решение для этого

params["due_date"] = {"date(3i)"=>"14", "date(2i)"=>"4", "date(1i)"=>"2014"}


params["due_date"].map{|k,v| v}.join("-").to_date
=> Mon, 14 Apr 2014
1 голос
/ 01 мая 2014
Date.new(*params["due_date"].values.map(&:to_i))

Примечание: работает в ruby ​​1.9.2+, так как это зависит от порядка элементов хеша.

Здесь есть две полезности:

1 голос
/ 08 мая 2013

Вот общий способ сделать это, который также поддерживает частичные даты / время и пустые поля:

def date_from_date_select_fields(params, name)
  parts = (1..6).map do |e|
    params["#{name}(#{e}i)"].to_i
  end

  # remove trailing zeros
  parts = parts.slice(0, parts.rindex{|e| e != 0}.to_i + 1)
  return nil if parts[0] == 0  # empty date fields set

  Date.new(*parts)
end

Пример использования:

# example input:
#
# params = {
#   "user":
#     "date_of_birth(1i)": "2010",
#     "date_of_birth(2i)": "8",
#     "date_of_birth(3i)": "16"
#   }
# }
date_of_birth = date_from_date_select_fields(params[:user], 'date_of_birth')
0 голосов
/ 17 августа 2010

Этот конкретный код (тот, который выполняет преобразование) может быть отслежен с 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/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...