Search code examples
ruby-on-railsformsdrop-down-menudefaultsimple-form

Setting a specific selected value in a Simple Form select box


I have a select box filled with options for a specific album type:

<select class="select optional" name="album[album_type_id]" id="album_album_type_id">
  <option value="1">Collaborative Album</option>
  <option selected="selected" value="2">Compilation Album</option>
  <option value="2">EP</option>
  <option value="3">Soundtrack</option>
  <option value="4">Studio Album</option>
</select>

I'd like to set Studio Album as the default value. I understand I could do the following:

<%= f.input :album_type_id, as: :select, collection: @album_types, selected: 4 %>

but more album types are bound to be added in the future and would much rather target it's string literal title. What would be the best way approach in using this for SimpleForms 'selected` parameter?


Solution

  • Agree on previous answer being the ideal. In the meantime, I'd use a helper:

    <%= f.input :album_type_id, as: :select, collection: @album_types, selected: get_index_by_name(@albums, 'Studio Album') %>
    

    Then in helpers/album_helper.rb:

    module AlbumHelper
      def get_index_by_name(albums, name)
        albums.first { |album| album.name == name }.id
      end 
    end
    


    Or as it's an instance variable you could do this, but maybe it's less reusable:

    <%= f.input :album_type_id, as: :select, collection: @album_types, selected: get_album_index_of('Studio Album') %>
    

    Then the helper:

    module AlbumHelper
      def get_album_index_of(name)
        @albums.first { |album| album.name == name }.id
      end 
    end
    


    Or perhaps a generic one to use across the whole site if there will be other dropdowns:

    <%= f.input :album_type_id, as: :select, collection: @album_types, selected: get_index_by_attribute(@albums, :name, 'Studio Album') %>
    

    In application_helper.rb:

    module ApplicationHelper
      def get_index_by_attribute(collection, attribute, value)
        collection.first { |item| item.send(attribute) == value }.id
      end 
    end