问题
I want to limit the entry possibilities for a text field in my model to a previously defined array.
How do I make an options_for_select with just a 1-dimensional array like ["foo","bar","foobar"]?
I tried
form_for @mappings do |f|
f.select(:mapping_type, options_for_select(["foo","bar","foobar"]), class: "..."
end
But the select box comes out all messed up like this:
<select name="section_mapping[mapping_type]" id="section_mapping_mapping_type">
as opposed to what it should be:
<select name="mapping_type" >
EDIT:
I changed the f.select to select_tag and the form shows up without any errors but when I submit it, it leaves that field empty
EDIT 2:
f.collection_select(:mapping_type, options_for_select([...]), class: "..."
works as in it submits the form with the value correctly, but the HTML class is not applied. Why is that?
回答1:
Basically, you want to be able to tie your collection select to a property of the object (in your case, @mappings)
Also, from the doc on rails collection_select, it will take options as follow:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) public
- Objet: the object you are binding the selected option to (@mappings [
f]) in this case - method: The property/attribute of the object (in this case,
mapping_type) - collection: The collection for select (
["foo","bar","foobar"]) - value_method: The value you want to send back with the submit (Note that this is a
methodwhich means you should be able to call it on an object.) more on this later. - text_method: The value you want to show as text on the select option on the view (this is also a method as above, more on this later as well)
- options: any additional option you want, (e.g:
include_blank) - html_options: eg:
id,classetc.
As concerning the value_method and text_method, these are methods that should be called on your collection, which means that your collection will be an array of objects.
To this end, you can have the following:
class CollectionArr
include ActiveModel::Model
attr_accessor :name
ARR = [
{"name" => "foo"},
{"name" => "bar"},
{"name" => "foobar"}
]
def self.get_collection
ARR.collect do |hash|
self.new(
name: hash['name']
)
end
end
end
From here, calling CollectionArr.get_collection will return an array of objects where you can cal .name to return either foo, bar, or foobar. This makes using the collection_select and easy deal from here:
<%= f.collection_select : mapping_type, CollectionArr.get_collection, :name, :name, {:include_blank => "Select one"} %>
And all is green...
来源:https://stackoverflow.com/questions/33880045/rails-form-for-model-select-box-with-1-dimensional-data