オプションがわからないのでソースみた(datetime_select編)
datetime_select使うとき、オプションがわからなかったんで調べた方法と結果を晒しまふ。
datetime_selectって、年月日時分まで表示してくれるんですが、英語で月を表示してるのと今回の要件だと
年月日しか要らなかったので、表示を変えたいなーと思ってソース調べました。*1
てか、基本的なヘルパがわからないあたり、こいつコード弄ってねえじゃん(プ
みたいな・・・・。
ralisのソースにgrep をかける。
grep -R datetime_select vendor/rails | grep def
そしたら、actionpack/lib/action_view/helpers/date_helper.rbに書いてあったので、これを開く。
def datetime_select(object_name, method, options = {}) InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_datetime_select_tag(options) end
というわけで、InstanceTagを探す。
date_helper.rb内部にありました。
class InstanceTag #:nodoc: include DateHelper …(略)…
んー、InstanceTagクラスを作成してその内部メソッドのto_datetime_select_tagを呼び出してるっぽいですね。
っていうわけで、to_datetime_select_tagを探します。
def to_datetime_select_tag(options = {}) date_or_time_select options end
もろ呼び出してるだけなので、date_or_time_selectを探しに行きます。
def date_or_time_select(options) defaults = { :discard_type => true } options = defaults.merge(options) datetime = value(object) datetime ||= Time.now unless options[:include_blank] position = { :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6 } order = (options[:order] ||= [:year, :month, :day]) # Discard explicit and implicit by not being included in the :order discard = {} discard[:year] = true if options[:discard_year] or !order.include?(:year) discard[:month] = true if options[:discard_month] or !order.include?(:month) discard[:day] = true if options[:discard_day] or discard[:month] or !order.include?(:day) discard[:hour] = true if options[:discard_hour] discard[:minute] = true if options[:discard_minute] or discard[:hour] discard[:second] = true unless options[:include_seconds] && !discard[:minute] # Maintain valid dates by including hidden fields for discarded elements [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) } # Ensure proper ordering of :hour, :minute and :second [:hour, :minute, :second].each { |o| order.delete(o); order.push(o) } date_or_time_select = '' order.reverse.each do |param| # Send hidden fields for discarded elements once output has started # This ensures AR can reconstruct valid dates using ParseDate next if discard[param] && date_or_time_select.empty? date_or_time_select.insert(0, self.send("select_#{param}", datetime, options_with_prefix(position[param], options.merge(:use_hidden => discard[param])))) date_or_time_select.insert(0, case param when :hour then (discard[:year] && discard[:day] ? "" : " — ") when :minute then " : " when :second then options[:include_seconds] ? " : " : "" else "" end) end date_or_time_select end
これでやってますねー。ってことで、:discard_hourオプションを与えてあげれば時、分って無くなるってわかったんですが、月が英語の理由がわかんねーっす。
途中で date_or_time_select.insert(0, self.send("select_#{param}", datetime, options_with_prefix(position[param], options.merge(:use_hidden => discard[param]))))って一行がありますが、ここでselect_yearとかselect_monthとか呼び出してそれぞれの値出してるみたいなので、monthの部分を見ます。
def select_month(date, options = {}) val = date ? (date.kind_of?(Fixnum) ? date : date.month) : '' if options[:use_hidden] hidden_html(options[:field_name] || 'month', val, options) else month_options = [] month_names = options[:use_month_names] || (options[:use_short_month] ? Date::ABBR_MONTHNAMES : Date::MONTHNAMES) month_names.unshift(nil) if month_names.size < 13 1.upto(12) do |month_number| month_name = if options[:use_month_numbers] month_number elsif options[:add_month_numbers] month_number.to_s + ' - ' + month_names[month_number] else month_names[month_number] end month_options << ((val == month_number) ? %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) : %(<option value="#{month_number}">#{month_name}</option>\n) ) end select_html(options[:field_name] || 'month', month_options, options) end end
なんかuse_month_numbersがあれば、数字をそのまま返してるみたいなので、use_month_number使えばOKとわかりました。
実はコメントにきちんと書いてあってそれ読めば良いんですが、英語が苦手なので英語のコメントよりソースの方先に読んだりする……。
俺のバーカ。
*1:date_selectで良いじゃん。と言うオチ。この日記書く為に調べてたらそのヘルパの存在を思い出したorz