问题
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
method
which 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
,class
etc.
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