如何从Rails中的date_select或select_date获取日期?

时间:2012-11-28 12:57:43

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

使用select_date为我提供了params[:my_date]yearmonthday属性。如何轻松获取Date对象?我希望有类似params[:my_date].to_date的东西。

我也很高兴使用date_select

8 个答案:

答案 0 :(得分:46)

使用date_select分别为日,月和年提供3个单独的键/值对。因此,您可以将它们作为参数传递给Date.new以创建新的Date对象。

示例date_select返回了Event模型的参数:

"event"=>
 {"name"=>"Birthday",
  "date(1i)"=>"2012",
  "date(2i)"=>"11",
  "date(3i)"=>"28"},

然后创建新的Date对象:

event = params[:event]
date = Date.new event["date(1i)"].to_i, event["date(2i)"].to_i, event["date(3i)"].to_i

您可以决定将此逻辑包装在方法中:

def flatten_date_array hash
  %w(1 2 3).map { |e| hash["date(#{e}i)"].to_i }
end

然后将其称为date = Date.new *flatten_date_array params[:event]。但这不是真正属于控制器的逻辑,因此您可能决定将其移动到其他位置。您甚至可以将其扩展到Date类,并将其称为date = Date.new_from_hash params[:event]

答案 1 :(得分:12)

这是另一个:

# view
<%= date_select('event', 'date') %>

# controller
date = Date.civil(*params[:event].sort.map(&:last).map(&:to_i))

找到http://kevinlochner.com/use-rails-dateselect-without-an-activerecord

答案 2 :(得分:3)

这是另一个

Date.civil(params[:event]["date(1i)"].to_i,params[:event]["date(2i)"].to_i,params[:event]["date(3i)"].to_i)

答案 3 :(得分:2)

这是rails 5的另一个:

module Convert
  extend ActiveSupport::Concern

  included  do
    before_action :convert_date
  end

  protected

  def convert_date
    self.params = ActionController::Parameters.new(build_date(params.to_unsafe_h))
  end

  def build_date(params)
    return params.map{|e| build_date(e)} if  params.is_a? Array

    return params unless params.is_a? Hash

    params.reduce({}) do |hash, (key, value)|
      if result = (/(.*)\(\di\)\z/).match(key)
        params_name = result[1]
        date_params = (1..3).map do |index|
          params.delete("#{params_name}(#{index}i)").to_i
        end
        hash[params_name] =  Date.civil(*date_params)
      else
        hash[key] = build_date(value)
      end

      hash
    end
  end
end

您需要将它包含在您的控制器或application_controller.rb中:

class ApplicationController < ActionController::Base
  include Convert
end

答案 4 :(得分:1)

使用date_select示例@ joofsh的答案,这是我使用的“一个班轮”,假设日期字段被称为start_date

ev_params = params[:event]

date = Time.zone.local(*ev_params.select {|k,v| k.to_s.index('start_date(') == 0 }.sort.map {|p| p[1].to_i})

答案 5 :(得分:1)

我使用以下方法,它具有以下好处:

  1. 它不必通过xxx(1i)明确命名参数键xxx(3i)(因此可以修改为仅通过将Date更改为{{1}来捕获小时和分钟});和
  2. 它从一组DateTime中提取日期,即使这些参数填充了许多其他键值对。
  3. params是格式params的哈希值; { xxx(1i): '2017', xxx(2i): 12, xxx(3i): 31, ... }是目标日期参数的公共子串date_key

    xxx

    我选择将其作为def date_from_params(params, date_key) date_keys = params.keys.select { |k| k.to_s.match?(date_key.to_s) }.sort date_array = params.values_at(*date_keys).map(&:to_i) Date.civil(*date_array) end 的类方法,而不是ApplicationRecord的实例辅助方法。我的理由是,在ActiveRecord实例化器( ApplicationController)中存在类似的逻辑来解析从Rails表单传递的日期。

答案 6 :(得分:0)

Rails 5 + 使用 select_date,在您的视图中注意前缀

<%= select_date Date.today - 3.months, prefix: :start_date %>

然后在您的控制器中您只需处理:

your_date = Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)

前缀将三个日期组件绑定到一个对象中。

答案 7 :(得分:-2)

或者干脆就这样做:

your_date_var = Time.parse(params[:my_date])