AM, PM+12時間表示で時間が指定できる時間選択を作りたい

http://d.hatena.ne.jp/sesejun/20070505/p1 の続き.railsの話.

時刻の指定でAMやPMを入れたいという場合,
date_helperのselect_hourではAM. PMの指定に対応していないようです.
ここでは,DateHelperのクラスを拡張します.

利用するcontrollerがreserves_controller.rbだとすると,
reserves_controller.rbの最後など,pathの通った所に,次のように書いて,
select_hour_ampmというメソッドを追加します.

module ActionView
 module Helpers
   module DateHelper
     def select_hour_ampm(datetime, options = {})
       val = datetime ? (datetime.kind_of?(Fixnum) ? datetime :
datetime.hour) : ''
       if options[:use_hidden]
         hidden_html(options[:field_name] || 'hour', val, options)
       else
         if val < 12
           ampm = "AM"
         else
           ampm = "PM"
           val -= 12
         end
         ampm_options = []
         ["AM","PM"].each do |ap|
           ampm_options << ((ampm == ap) ?
             %(<option value="#{ap}" selected="selected">#{ap}</option>\n) :
             %(<option value="#{ap}">#{ap}</option>\n)
           )
         end

         hour_options = []
         0.upto(12) do |hour|
           hour_options << ((val == hour) ?
             %(<option value="#{leading_zero_on_single_digits(hour)}"
selected="selected">#
{leading_zero_on_single_digits(hour)}</option>\n) :
             %(<option
value="#{leading_zero_on_single_digits(hour)}">#{leading_zero_on_sin
gle_digits(hour)}</option>\n)
           )
         end
       select_html('ampm', ampm_options, options) +
select_html(options[:field_name] || 'ho
ur', hour_options, options)
       end
     end
   end
 end
end

また,reserves_controllerでAM, PMをハンドルできるように
reserves_controllerのcreateメソッドの一番始めに,
次のコードを入れます(editメソッドも同様に変更します).

   puts "AMPM:" + params[:reserve][:ampm]
   puts  params[:reserve]["start_time(4i)"]
   if params[:reserve][:ampm] == "PM"
     v = params[:reserve]["start_time(4i)"]
     params[:reserve]["start_time(4i)"] = (v.to_i + 12).to_s
   end
   params[:reserve].delete(:ampm)
# ここまでが追加,以下は今までと同じ
   @reserve = reserve.new(params[:reserve])
...

そして,new.rhtml のselect_hour の代わりに,
次のように今作成した select_hour_ampm を利用してあげます.

<%= select_hour_ampm Time.now, {:prefix=>"reserve",
:field_name=>"start_time(4i)" } %>

AM, PMを選ぶことができるようになって,保存するときには24時間表示に変更して保存します.

  • 反省点1.select_hour をoptionで拡張したほうがよかったかな
  • 反省点2.DateHelperで完結していなくて,controllerにも細工(PMの場合に時間を+12する)をしないといけないのが,いまいちいけてないな.