Using select method in form_for in rails - ruby-on-rails

I would like to use a method inside a form_for in rails to create a select tag with options where the value of the options come from one array and the options enclosed by the option tags come from another array.
For example, the first option would be:
<option value = Array1[0]> Array2[0] </option>
How do I do this? Can I use 'select' such as:
= form_for #activity do |f|
= f.select(Array1, Array2, {:selected => nil, :prompt => 'Select Stage'})
I couldn't get something like this working, even though this format seemed consistent with options_for_select as described in the rails API at api.rubyonrails.org.

Try this:
= f.select(:method, Array2.zip(Array1), { :selected => nil, :prompt => 'Select Stage' })
The zip method will combine two arrays to make one two-dimensional array.
So, for example, [1,2,3].zip([4,5,6]) will return [[1,4], [2,5], [3,6]].
select can then interpret this as a list of option texts and option values.
Given [['Male', 'm'], ['Female', 'f']], select will return
<option value="m">Male</option>
<option value="f">Female</option>

Related

Match an option in select form with boolean values

I have the following piece of code
%br
= f.label :active, 'Status'
= f.select :active, ['Active','Inactive']
Symbol :active is a boolean type var. How can i match Active => 1/True, and Inactive => 0/False , for the database adding.
Sorry for the newbie question, but i can't figure it out.
You can provide a pair of values for each options: first will be used as label (inner text of <option> tag), second will be used as a value attribute:
= f.select :active, [['Active', true], ['Inactive', false]]
It'll render something like:
<select name="model[active]">
<option value="true">Active</option>
<option value="false">Inactive</option>
</select>
Have a look at the docs for select and options_for_select.
A small extension of the earlier answer, if you're using a dropdown.
I needed to use "options_for_select." Also, ":selected" stores the value for the next time you return to the form.
<%= f.select(:active, options_for_select([['Active', true], ['Inactive', false]], {:selected => #symbol.active}),:prompt => "Select") %>

Array as Parameter from Rails Select Helper

I'm working on a legacy project that is using acts_as_taggable_on which expects tags to come in arrays. I have a select box allowing users to select a tag on a Course in a field called categories. The only way mass assignment create will work is if params looks like this params = {:course => {:categories => ['Presentation']}}. I've currently a view with this helper:
<%= f.select 'categories', ['Presentation' , 'Round Table' , 'Demo', 'Hands-on'] %>
Which will give me a parameter like params = {:course => {:categories => 'Presentation'}}. This doesn't work since Acts as tag gable apparently can't handle being passed anything other than a collection.
I've tried changing categories to categories[] but then I get this error:
undefined method `categories[]' for #<Course:0x007f9d95c5b810>
Does anyone know the correct way to format my select tag to return an array to the controller? I'm using Rails 3.2.3
I didn't work with acts_as_taggable_on, but maybe this simple hack will be suitable for you? You should put it before mass-assignment.
category = params[:course][:categories]
params[:course][:categories] = [category]
If you are only going to allow the selection of ONE tag, you could do:
<%= f.select 'categories', [['Presentation'] , ['Round Table'] , ['Demo'], ['Hands-on']] %>
Each one item array will have first for the display value, and last for the return value, which in this case will both return the same thing, as the first element of the array is the same as the last element when the array as one element.
Seems like select doesn't give you that option.
If I understand correctly, one option might be to use a select_tag instead and just be explicit about where you want the selection in the params:
<%= select_tag 'course[categories][]', options_for_select(['Presentation' , 'Round Table' , 'Demo', 'Hands-on']) %>
That ought to get your params the way you need them.
Here's what I'm using for one of my projects:
<% options = { include_blank: true } %>
<% html_options = { required: true, name: "#{f.object_name}[#{resource.id}][days][]" } %>
<%= f.select :days, DAYS, options, html_options %>
Without html_options[:name], Rails handles the name of the select tag and spits out something like
service[service_add_ons_attributes][11][days]
but I need
service[service_add_ons_attributes][11][days][]
So I override it.
Hope that helps.

Rails FormTagHelper missing important select and collection_select methods

You can do this when you use form_for(#model...):
collection_select(:subscription, :duration, ["Some", "Values"], :to_s, :to_s, {:prompt => true})
And the output is something like this:
<select id="subscription_duration" name="subscription[duration]">
<option value="">Please select</option>
<option value="Some">Some</option>
<option value="Values">Values</option>
</select>
If you use a form without a model, you don't have that nice helper method to create the <option> tags for you. Instead, you have to do this:
select_tag("subscription", '<option value="Some">Some</option><option value="Values">Values</option>')
FormHelper and FormOptionsHelper work together on a form wrapping a model, and they have the select and collection_select to make life easy. For a plain form_tag (without a model), however, there is no such FormOptionsTagHelper. FormTagHelper has a select_tag method, but you have to manually write out the options which is a waste. It seems like this has been fixed somewhere.
I could write my own helper to get rid of writing those option tags manually, but thats what FormOptionsHelper#collection_select does... Is there an equivalent out there for forms without models?
select and collection_select can be called without a model. I usually use a combination of two significant words, and an array of pairs [label, value] to select. The only drawback is having to use the format abc[xyz].
You tried to use options_for_select?
select_tag 'Account', options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")

rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use?
I can't see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a scenario where collection_select is better than select? or is anything I am missing here?
collection_select is intended to be used when the list of items is an array of ActiveRecord objects. collection_select is built on the top of select so it's a convenient method when you need to display a collection of objects and not an array of strings.
collection_select(:post, :author_id, Author.find(:all), :id, :name)
I have written something on that a while back, have a look at
http://nasir.wordpress.com/2007/11/02/not-binding-your-selection-list-to-a-particular-model-in-rails/
Hope that helps
And regarding select, you can use it with a Hash. I used to use it with ENUM.
# In a hypothetical Fruit model
enum types: { 'Banana' => 0, 'Grape' => 1, 'Mango' => 2 }
# In the view
f.select :type, Fruits.types.invert
Note that I had to use invert in order to show the correct value in option:
<select>
<option value="0">Banana</option>
<option value="1">Grape<option>
<option value="2">Mango</option>
</select>
To refer to it in a show file you can use Fruit.types and this will return our previous Hash. This way you can do:
Fruit.types[obj.type]
Last note: You can use symbols instead numbers if you prefer enum types: { 'Banana' => :banana, ...and you will get <option value="banana">Banana</option>

select_tag is sorting (strangely) [Rails]

I have a select box that looks like this (within a form_for)
<%=f.select(:whatever_id, {"blah"=>0, "blah2"=>1, "blah3"=>2, "blah4"=>3}, {:include_blank => true}) %>
and the output is good, but weird... like this:
<select id="personal_information_whatever_id" name="personal_information[whatever_id]"><option value=""></option>
<option value="1">blah2</option>
<option value="2">blah3</option>
<option value="0">blah</option>
<option value="3">blah4</option></select>
But I want it to go in order... what is happening, and how can I correct it?
Edit: I feel like the answer has to do with this
You can never be guaranteed of any
order with hashes. You could try
.sort() to sort the values in
alphabetical order.
is there anything I can use aside from a hash?
Yes, you should use an array of arrays. The easiest way with your example would be something like this:
<%=f.select(:whatever_id, [["blah", 0], ["blah2", 1], ["blah3", 2], ["blah4", 3]], {:include_blank => true}) %>
This should suffice. Take a look at the docs at api.rubyonrails.com too.
In your model, define your hash (in your case your model is "whatever" and your hash "blahs"):
BLAHS = { "blah"=>0, "blah2"=>1, "blah3"=>2 }
In the select tag where you put your hash, type
Whatever::BLAHS.sort {|a,b| a[1] <=> b[1]}
This creates an array as described in other answers, ordered by the second item (the id/numbers).
After saving, when you pull a Whatever back out of the database and want to show the field blah, do this
Whatever::BLAHS.index whatever.blah
The array of arrays mentioned by others works, but when you want to show a Whatever, how do you show the value of blah in a nice way? I recommend sticking with the hash as it solves this problem.
The problem is that the options parameter is a hash, and hashes have no guaranteed order.
This should work for you
<%= f.select(:whatever_id, ([["blah",0],["blah2",1],["blah3",2]]), {:include_blank => true}) %>
Edit in response to your comment: For collections see collection_select

Resources