将数据从`datetime_select`转换为DateTime对象的Rails方法在哪里?

时间:2011-02-22 03:41:02

标签: ruby-on-rails-3

当我们在表单中使用<%= 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方法为我执行此操作。

问题是,我不知道在哪里寻找那种方法。

聚苯乙烯。我最终试图解决这个问题other problem,这个问题是尝试找到解决其他问题的第一步。

7 个答案:

答案 0 :(得分:24)

保存模型时,此转换在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::newDateTime::civilruby-doc

的别名

答案 1 :(得分:16)

该代码路径的开头似乎是正确的:

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

发现这很棘手!我希望这可以帮助你找到你需要的东西

答案 2 :(得分:7)

您好我在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

答案 3 :(得分:2)

其他人提供了使用DateTime.new的解决方案,但这在Postgresql中不起作用。这样就会保存记录,就像它在表单中插入一样,因此如果你使用的是“没有时区的时间戳”,它就不会像在utc时间那样保存在数据库中。我花了好几个小时试图找出这个,解决方案是使用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)

答案 4 :(得分:1)

必须做一些非常相似的事情,并最终使用这种方法:

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

答案 5 :(得分:0)

我在Rails 4中遇到了这个问题。事实证明我忘了将允许的参数添加到我的控制器中:

def event_params
  params.require(:event).permit(....., :start_time, :end_time,...)
end

答案 6 :(得分:-2)

这是我使用的方法 - 它将删除的密钥作为新哈希返回。

class Hash
   def delete_by_keys(*keys)
     keys.each_with_object({}) { |k, h| h[k] = delete(k) if include? k }
  end
end