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

时间:2021-07-22 21:32:02

Using select_date gives me back a params[:my_date] with year, month and day attributes. How do get a Date object easily? I'm hoping for something like params[:my_date].to_date.

使用select_date会给我一个带有年,月和日属性的参数[:my_date]。如何轻松获取Date对象?我希望像params [:my_date] .to_date这样的东西。

I'm happy to use date_select instead as well.

我也很高兴使用date_select。

7 个解决方案

#1


43  

Using date_select gives you 3 separate key/value pairs for the day, month, and year respectively. So you can pass them into Date.new as parameters to create a new Date object.

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

An example date_select returned params for an Event model:

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

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

Then to create the new Date object:

然后创建新的Date对象:

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

You may instead decide to wrap this logic in a method:

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

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

And then call it as date = Date.new *flatten_date_array params[:event]. But this is not logic that truly belongs in a controller, so you may decide to move it elsewhere. You could even extend this onto the Date class, and call it as date = Date.new_from_hash params[:event].

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

#2


11  

Here is another one:

这是另一个:

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

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

Found at http://kevinlochner.com/use-rails-dateselect-without-an-activerecord

发现于http://kevinlochner.com/use-rails-dateselect-without-an-activerecord

#3


3  

Here is the another one

这是另一个

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

#4


1  

With the date_select example @joofsh's answer, here's a "one liner" I use, presuming the date field is called start_date:

使用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


0  

Here is another one for rails 5:

这是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

You need to include it to your controller or application_controller.rb:

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

class ApplicationController < ActionController::Base
  include Convert
end

#6


0  

I use the following method, which has the following benefits:

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

  1. it doesn't have to explicitly name param keys xxx(1i) through xxx(3i) (and thus could be modified to capture hour and minute simply by changing Date to DateTime); and
  2. 它不必明确地命名param键xxx(1i)到xxx(3i)(因此可以修改为仅通过将Date更改为DateTime来捕获小时和分钟);和
  3. it extracts a date from a set of params even when those params are populated with many other key-value pairs.
  4. 它从一组参数中提取日期,即使这些参数填充了许多其他键值对。

params is a hash of the format { xxx(1i): '2017', xxx(2i): 12, xxx(3i): 31, ... }; date_key is the common substring xxx of the target date parameters.

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

I chose to place this as a class method of ApplicationRecord, rather than as an instance helper method of ApplicationController. My reasoning is that similar logic exists within the ActiveRecord instantiator (i.e., Model.new) to parse dates passed in from Rails forms.

我选择将它作为ApplicationRecord的类方法,而不是作为ApplicationController的实例辅助方法。我的理由是,ActiveRecord实例化器(即Model.new)中存在类似的逻辑来解析从Rails表单传递的日期。

#7


-1  

Or simply do this:

或者只是这样做:

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

#1


43  

Using date_select gives you 3 separate key/value pairs for the day, month, and year respectively. So you can pass them into Date.new as parameters to create a new Date object.

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

An example date_select returned params for an Event model:

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

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

Then to create the new Date object:

然后创建新的Date对象:

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

You may instead decide to wrap this logic in a method:

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

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

And then call it as date = Date.new *flatten_date_array params[:event]. But this is not logic that truly belongs in a controller, so you may decide to move it elsewhere. You could even extend this onto the Date class, and call it as date = Date.new_from_hash params[:event].

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

#2


11  

Here is another one:

这是另一个:

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

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

Found at http://kevinlochner.com/use-rails-dateselect-without-an-activerecord

发现于http://kevinlochner.com/use-rails-dateselect-without-an-activerecord

#3


3  

Here is the another one

这是另一个

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

#4


1  

With the date_select example @joofsh's answer, here's a "one liner" I use, presuming the date field is called start_date:

使用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


0  

Here is another one for rails 5:

这是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

You need to include it to your controller or application_controller.rb:

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

class ApplicationController < ActionController::Base
  include Convert
end

#6


0  

I use the following method, which has the following benefits:

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

  1. it doesn't have to explicitly name param keys xxx(1i) through xxx(3i) (and thus could be modified to capture hour and minute simply by changing Date to DateTime); and
  2. 它不必明确地命名param键xxx(1i)到xxx(3i)(因此可以修改为仅通过将Date更改为DateTime来捕获小时和分钟);和
  3. it extracts a date from a set of params even when those params are populated with many other key-value pairs.
  4. 它从一组参数中提取日期,即使这些参数填充了许多其他键值对。

params is a hash of the format { xxx(1i): '2017', xxx(2i): 12, xxx(3i): 31, ... }; date_key is the common substring xxx of the target date parameters.

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

I chose to place this as a class method of ApplicationRecord, rather than as an instance helper method of ApplicationController. My reasoning is that similar logic exists within the ActiveRecord instantiator (i.e., Model.new) to parse dates passed in from Rails forms.

我选择将它作为ApplicationRecord的类方法,而不是作为ApplicationController的实例辅助方法。我的理由是,ActiveRecord实例化器(即Model.new)中存在类似的逻辑来解析从Rails表单传递的日期。

#7


-1  

Or simply do this:

或者只是这样做:

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