Rails - return an array of months for a select tag

15,986

Solution 1

Try this!

@months = [['-', '']]
(1..12).each {|m| @months << [Date::MONTHNAMES[m], m]}

Solution 2

Date::MONTHNAMES.each_with_index.collect{|m, i| [m, i]}
=> [[nil, 0], 
    ["January", 1], 
    ["February", 2], 
    ["March", 3], 
    ["April", 4], 
    ["May", 5], 
    ["June", 6], 
    ["July", 7], 
    ["August", 8], 
    ["September", 9], 
    ["October", 10], 
    ["November", 11], 
    ["December", 12]]

Abbreviated selection with default option

Date::ABBR_MONTHNAMES.compact.each_with_index.collect{|m, i| [m, i+1]}
                     .insert(0, ['Please Select', nil])
=> [["Please Select", nil], 
    ["Jan", 1], 
    ["Feb", 2], 
    ["Mar", 3], 
    ["Apr", 4], 
    ["May", 5], 
    ["Jun", 6], 
    ["Jul", 7], 
    ["Aug", 8], 
    ["Sep", 9], 
    ["Oct", 10], 
    ["Nov", 11], 
    ["Dec", 12]]

Solution 3

You can use rails helper select_month, like:

select_month(Date.today)

Solution 4

Here's a sexy way to get the months only if that's all you want:

Date::MONTHNAMES.slice(1..-1).map(&:to_sym)

Solution 5

This is my solution for you, in case you work with I18n-based projects, that requires multilingual features:

def month_array
  # Gets the first day of the year
  date = Date.today.beginning_of_year
  # Initialize the months array
  months = {}

  # Iterate through the 12 months of the year to get it's collect
  12.times do |i| # from 0 to 11
    # Get month name from current month number in a selected language (locale parameter)
    month_name = I18n.l(date + i.months, format: '%B', locale: :en).capitalize
    months[month_name] = i + 1
  end
  return months
end

# => {"January"=>1, "February"=>2, "March"=>3, "April"=>4, "May"=>5, "June"=>6, "July"=>7, "August"=>8, "September"=>9, "October"=>10, "November"=>11, "December"=>12}

Regards

Share:
15,986

Related videos on Youtube

Kevin Whitaker
Author by

Kevin Whitaker

Updated on May 27, 2022

Comments

  • Kevin Whitaker
    Kevin Whitaker almost 2 years

    I'm in an app that is on Rails 2.3.8, and need to return an array of month names and numbers to be plugged into an options_for_select statement. What I've got so far is kind of working, but not really. The reason I'm doing things this way is because the select statement needs a prompt, which you can't give options_for_select by default in 2.3.8 (at least to my knowledge).

    Here is what I have so far:

    @months = [['-', '']]
    (1..12).each {|m| @months << [[Date::MONTHNAMES[m], m]]}
    

    So what I'm looking to get returned are options like this:

    <option value="1">January</option>
    <option value="2">February</option>
    

    However, instead I get:

    <option value="January1">January1</option>
    <option value="February2">February2</option>
    

    What am I missing?

  • Douglas F Shearer
    Douglas F Shearer about 13 years
    Yep, too many brackets. You can compress it even more using map, and pass it to options_for_select: options_for_select((1..12).map {|m| [Date::MONTHNAMES[m], m]}).
  • iwasrobbed
    iwasrobbed about 13 years
    @Douglas: I would upvote your answer if you had left it as one :)
  • Dmitry
    Dmitry over 11 years
    This is awesome! And brilliant update by @DouglasFShearer! This is exactly one of the reasons I'm moving to Ruby from Python, lol
  • cman77
    cman77 over 7 years
    In case anyone is looking for how to do this while supporting internationalization: (1..12).map {|m| I18n.l(DateTime.parse(Date::MONTHNAMES[m]), format: "%B")}
  • RoRFan
    RoRFan about 3 years
    You can use Date::MONTHNAMES.compact if you want to remove nil values