使用select_date
給我一個params[:my_date]
與year
,month
和day
屬性。如何輕鬆獲取Date對象?我希望有像params[:my_date].to_date
這樣的東西。如何從date_select或select_date在Rails中獲取日期?
我很樂意使用date_select
。
使用select_date
給我一個params[:my_date]
與year
,month
和day
屬性。如何輕鬆獲取Date對象?我希望有像params[:my_date].to_date
這樣的東西。如何從date_select或select_date在Rails中獲取日期?
我很樂意使用date_select
。
使用date_select將分別爲日,月和年分別提供3個單獨的鍵/值對。因此,您可以將它們傳遞到Date.new
作爲參數來創建新的Date對象。
一個例子date_select返回PARAMS用於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]
。
這裏是另一個問題:
# 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
沒有爲我工作。 –
它適合我。我會避免雙重映射,如date = Date.civil(* params [:event] .sort.map {| d | d.last.to_i}) – Jared
發現這裏是另外一個
Date.civil(params[:event]["date(1i)"].to_i,params[:event]["date(2i)"].to_i,params[:event]["date(3i)"].to_i)
隨着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:
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
或者乾脆做到這一點:
your_date_var = Time.parse(params[:my_date])
params [:my_date]將爲零 –
我用下面的方法,它有以下好處:
xxx(1i)
通過xxx(3i)
(因此可以被修改簡單地通過改變Date
到DateTime
捕捉到小時和分鐘);和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
一個類的方法,而不是作爲ApplicationController
實例的輔助方法。我的推理是在ActiveRecord實例化器(,即Model.new
)內存在類似的邏輯來解析從Rails表單傳入的日期。
非常令人驚訝的是,Rails不包含簡單的轉換機制,因爲在將日期選擇附加到模型時,它們已經具有隱藏機制。我在Rails指南文檔中發現他們建議使用'Date.civil',那和'Date.new'有什麼區別? –
@at。根據ruby文檔,「Date.civil」和「Date.new」完全相同。我一直使用'Date.new'作爲更多的OOP-ish。而且我同意你的看法,我也很驚訝它不是內置在rails中。但是像上面這種簡單的1行方法是一個非常簡單的修復方法。 – joofsh
聽起來不太難實施,因爲 – BKSpurgeon