如何将rails中date_select返回的哈希值转换为Date对象?

我在视图中的一个表单中有一个date_select,但是在提交时,返回的值是一个散列forms,如下所示:

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

如何将其转换为rails中的Date格式,以便在查询数据库时将其用作条件,例如:condition => {:dates == :some_date_from_date_select} ? 我试着调用Date.parse(:some_date_from_date_select)但它不起作用,因为它期望一个字符串而不是一个哈希映射。

有没有铁路方式来做到这一点?

谢谢

我不知道有关导轨的方式,但这种“单线程”可以解决问题:

 irb(main):036:0> d = Date.parse( {"(1i)"=>"2010", "(2i)"=>"8", "(3i)"=>"16"}.to_a.sort.collect{|c| c[1]}.join("-") ) => # 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" 

我有一个简短的一行解决方案

 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 

这是一种通用的方法,它还支持部分日期/时间和空字段:

 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') 
 Date.new(*params["due_date"].values.map(&:to_i)) 

注意:在ruby 1.9.2+中工作,因为它取决于哈希元素的顺序。

这里有两个好东西:

  • 符号到Proc
  • Splat操作员

可以从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/