Где метод Rails, который преобразует данные из `datetime_select` в объект DateTime? - PullRequest
30 голосов
/ 22 февраля 2011

Когда мы используем <%= f.datetime_select :somedate %> в форме, он генерирует HTML как:

<select id="some_date_1i" name="somedate1(1i)">  #year
<select id="some_date_2i" name="somedate1(2i)">  #month
<select id="some_date_3i" name="somedate1(3i)">  #day
<select id="some_date_4i" name="somedate1(4i)">  #hour
<select id="some_date_5i" name="somedate1(5i)">  #minute

Когда эта форма отправляется, принимаются значения somedate1(<n>i):

{"date1(1i)"=>"2011", "date1(2i)"=>"2", "date1(3i)"=>"21", "date1(4i)"=>"19", "date1(5i)"=>"25"}

Как я могу преобразовать это в объект DateTime? Я мог бы написать свой собственный метод для этого, но так как Rails уже способен выполнять преобразование, мне было интересно, могу ли я вызвать этот метод Rails, чтобы сделать это для меня.

Проблема в том, что я не знаю, где искать этот метод.

Ps. В конечном итоге я пытаюсь решить эту другую проблему , которая у меня есть, и этот вопрос является первым шагом в попытке найти решение этой другой проблемы.

Ответы [ 7 ]

24 голосов
/ 22 февраля 2011

Это преобразование происходит в ActiveRecord при сохранении модели.

Вы можете обойти это как-то так:

somedate = DateTime.new(params["date1(1i)"].to_i, 
                        params["date1(2i)"].to_i,
                        params["date1(3i)"].to_i,
                        params["date1(4i)"].to_i,
                        params["date1(5i)"].to_i)

DateTime::new - псевдоним DateTime::civil ( ruby-doc )

16 голосов
/ 22 февраля 2011

Начало этого пути к коду, похоже, прямо здесь:

https://github.com/rails/rails/blob/d90b4e2/activerecord/lib/active_record/base.rb#L1811

Это было сложно найти! Я надеюсь, что это поможет вам найти то, что вам нужно

7 голосов
/ 30 марта 2012

Привет! Я добавил следующее в ApplicationController, и он выполняет это преобразование.

    #extract a datetime object from params, useful for receiving datetime_select attributes
    #out of any activemodel
    def parse_datetime_params params, label, utc_or_local = :local
      begin
        year   = params[(label.to_s + '(1i)').to_sym].to_i
        month  = params[(label.to_s + '(2i)').to_sym].to_i
        mday   = params[(label.to_s + '(3i)').to_sym].to_i
        hour   = (params[(label.to_s + '(4i)').to_sym] || 0).to_i
        minute = (params[(label.to_s + '(5i)').to_sym] || 0).to_i
        second = (params[(label.to_s + '(6i)').to_sym] || 0).to_i

        return DateTime.civil_from_format(utc_or_local,year,month,mday,hour,minute,second)
      rescue => e
        return nil
      end
    end
2 голосов
/ 29 апреля 2014

Кто-то здесь предложил решение использовать DateTime.new, но это не сработает в Postgresql.Это сохранит запись как есть, то есть как она была вставлена ​​в форму, и, таким образом, она не будет сохраняться в базе данных как время без прерывания, если вы используете «метку времени без часового пояса».Я потратил часы, пытаясь выяснить это, и решение было использовать Time.new, а не DateTime.new:

datetime = Time.new(params["fuel_date(1i)"].to_i, params["fuel_date(2i)"].to_i, 
                        params["fuel_date(3i)"].to_i, params["fuel_date(4i)"].to_i,
                        params["fuel_date(5i)"].to_i)
1 голос
/ 26 марта 2016

Пришлось сделать что-то очень похожее, и в итоге использовал этот метод:

def time_value(hash, field)
  Time.zone.local(*(1..5).map { |i| hash["#{field}(#{i}i)"] })
end

time = time_value(params, 'start_time')

См. Также: TimeZone.local

0 голосов
/ 22 декабря 2016

Я использую этот метод - он возвращает удаленные ключи как новый хэш.

class Hash
   def delete_by_keys(*keys)
     keys.each_with_object({}) { |k, h| h[k] = delete(k) if include? k }
  end
end
0 голосов
/ 22 февраля 2016

У меня была эта проблема с Rails 4. Оказалось, что я забыл добавить разрешенные параметры в мой контроллер:

def event_params
  params.require(:event).permit(....., :start_time, :end_time,...)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...