格式化来自params的日期

时间:2013-03-21 20:05:41

标签: ruby-on-rails ruby-on-rails-3

在Grails中,如果我定义一个语言环境,并在i18n文件上设置特定格式的日期,如(dd / mm / AAAA),如果调用一个请求,如:

http://myapp/myaction?object.date=10/12/2013

当我得到print:params.date时,它会给我一个日期对象。

我怎样才能在轨道上做同样的事情?

1 个答案:

答案 0 :(得分:0)

通常,Rails会为您处理此问题。例如,表单助手datetime_select与某些activerecord magic一起使用 确保确保时间/日期类型在往返过程中幸存。标准的数据采集器有各种替代方案。

如果这对您不起作用,例如rails没有生成表单,有(至少)两个选项。

一个选项,稍微evi,是猴子补丁HashWithIndifferentAccess(由请求参数使用)根据密钥名称进行类型转换。它可能看起来像:

module AddTypedKeys

  def [](key)
    key?(key) ? super : find_candidate(key.to_s)
  end

private

  # look for key with a type extension  
  def find_candidate(key)
    keys.each do |k|
      name, type = k.split('.', 2)
      return typify_param(self[k], type) if name == key
    end
    nil
  end

  def typify_param(value, type)
    case type
      when 'date'
        value.to_date rescue nil
      else
        value
    end
  end   
end


HashWithIndifferentAccess.send(:include, AddTypedKeys)

这会以你描述的方式扩展params []。要在rais中使用它,您可以将其放入初始化程序,例如confg/initializers/typed_params.rb

要查看它是否有效,您可以使用

进行测试
params = HashWithIndifferentAccess.new({'a' => 'hello', 'b.date' => '10/1/2013', 'c.date' => 'bob'})
puts params['b.date'] # returns string 
puts params['b'] # returns timestamp
puts params['a'] # returns string
puts params['c'] # nil (invalid date parsed)

然而......我不确定这是值得的,它可能不适用于Rails 4 / StrongParameters。

更好的解决方案是在模型中使用虚拟属性。有关使用慢性病的一个非常好的例子,请参阅this SO post