Search code examples
ruby-on-railsdatabaseformsvalidation

Rails edit.html.erb form not pre-loading data for inputs with empty select option


I have a rails application that has 2 forms that edit the same table. The first form is in new.html.erb for basic information filled with text fields. Then the second form is edit.html.erb which is similar to the first form but adds a few options_for_select fields.

I want the options for select fields to have a default selection with empty value if the user has not yet added this information to the table. If the user does have the information saved already, the option should be pre-selected.

However, whenever I add an empty value options to these fields, the information gets saved to the database but the data does not show up as a pre-selected option next time.

Here are the 2 different ways I have tried:

<%= f.select( :attribute1, options_for_select( 
    [
      ["Select your attribute", "", { disabled: true }],
      ["option1", "option1"],
      ["option2","option2"]
    ],""))
%>

and

<%= f.select( :attribute1, options_for_select( 
    [
      ["Select your attribute", ""],
      ["option1", "option1"],
      ["option2","option2"]
    ],""))
%>

Both of those result in the data being saved to the database, but not showing up in the form on refresh. However, the following code does show the data on refresh:

<%= f.select( :attribute1, options_for_select( 
    [
      ["option1", "option1"],
      ["option2","option2"]
    ],""))
%>

However, the problem with this one is that if the user hasn't saved anything yet, option1 is the first selection, which I don't want, because if the user accidentally bypasses this question they should get a validation error telling them that it's blank, but with this code, an option is pre-selected as a default instead of an empty option.


Solution

  • options_for_select generates actual option tags:

    >> puts helper.options_for_select([["Select your attribute", ""], ["option1", "option1"], ["option2","option2"]]) 
    <option value="">Select your attribute</option>
    <option value="option1">option1</option>
    <option value="option2">option2</option>
    

    You'd have to specify which option is selected as a second argument:

    >> options = [["Select your attribute", ""], ["option1", "option1"], ["option2","option2"]]
    >> puts helper.options_for_select(options, "option1")
    #                                          ^^^^^^^^^
    <option value="">Select your attribute</option>
    <option selected="selected" value="option1">option1</option> # <=
    <option value="option2">option2</option>
    

    Or just pass an array to select instead:

    <%= f.select :attribute1,
      [
        ["option1", "option1"],
        ["option2", "option2"]
      ],
      include_blank: "Select your attribute"
    %>
    
    # if value and name are the same
    <%= f.select :attribute1,
      ["option1", "option2"],
      include_blank: "Select your attribute"
    %>