2012-11-28 29 views

回答

41

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

+9

非常令人驚訝的是,Rails不包含簡單的轉換機制,因爲在將日期選擇附加到模型時,它們已經具有隱藏機制。我在Rails指南文檔中發現他們建議使用'Date.civil',那和'Date.new'有什麼區別? –

+0

@at。根據ruby文檔,「Date.civil」和「Date.new」完全相同。我一直使用'Date.new'作爲更多的OOP-ish。而且我同意你的看法,我也很驚訝它不是內置在rails中。但是像上面這種簡單的1行方法是一個非常簡單的修復方法。 – joofsh

+0

聽起來不太難實施,因爲 – BKSpurgeon

3

發現這裏是另外一個

Date.civil(params[:event]["date(1i)"].to_i,params[:event]["date(2i)"].to_i,params[:event]["date(3i)"].to_i) 
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}) 
0

這裏是另一個用於軌道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 
-1

或者乾脆做到這一點:

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

params [:my_date]將爲零 –

0

我用下面的方法,它有以下好處:

  1. 它沒有明確地命名PARAM鍵xxx(1i)通過xxx(3i)(因此可以被修改簡單地通過改變DateDateTime捕捉到小時和分鐘);和
  2. 它從一組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表單傳入的日期。

相關問題