【问题标题】:Where is the Rails method that converts data from `datetime_select` into a DateTime object?将数据从 `datetime_select` 转换为 DateTime 对象的 Rails 方法在哪里?
【发布时间】:2011-07-01 17:16:03
【问题描述】:

当我在表单中使用<%= 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(&lt;n&gt;i) 值:

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

如何将其转换为 DateTime 对象?

我可以编写自己的方法来执行此操作,但由于 Rails 已经能够进行转换,我想知道是否可以调用该 Rails 方法来为我执行此操作?

我不知道去哪里找那个方法。

我最终试图解决“How to handle date/times in POST parameters?”,这个问题是试图找到解决其他问题的第一步。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      不得不做一些非常相似的事情,最终使用了这种方法:

      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

      【讨论】:

        【解决方案3】:

        我在使用 Rails 4 时遇到了这个问题。结果我忘记将允许的参数添加到我的控制器:

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

        【讨论】:

          【解决方案4】:

          这里的其他人提供了使用 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)
          

          【讨论】:

          • 当我这样做时,我无法访问我的参数。当我在 byebug 中输入“params”时,它会显示来自帖子的参数。当我输入“params [”fuel_date(1i)“].to_i”时,它给了我“nil”。知道为什么吗?
          • @camdixon 查看来自表单 POST 的参数哈希。这将告诉您要使用的确切字符串。就我而言,它是fuel_date,因为这是我分配给datetime_select 的符号,但在您的情况下,您可能使用了不同的符号。
          【解决方案5】:

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

          【讨论】:

          • 请注意,该救援子句中的 exp 类是 StandardError 而不是 Exception。我会考虑将其更改为“e”或“error”以避免任何混淆。
          【解决方案6】:

          当您保存模型时,此转换会在 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::civil (ruby-doc) 的别名

          【讨论】:

          • 不幸的是,这会导致 postgresql 的 utc 时间出现问题
          • @JohnMerlino 这已经很晚了,但是您可以在将时间保存到 Postgres 之前使用 Ruby 将时间转换为 UTC(或您想要的任何时区),并在检索时将其转换回 X 语言环境它来自数据库。事实上,以UTC存储并转换客户端是general thing that you do
          【解决方案7】:

          该代码路径的开始,似乎就在这里:

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

          这很难找到!我希望这可以帮助您找到所需的内容

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多