Why does my select box display things backwards in rails? - ruby-on-rails

I have the following view code:
<%= f.select :day_of_play, Team::DAYS_OF_WEEK %>
And I have to create the following map for it to work and display a select box:
DAYS_OF_WEEK = {"Sunday" => 0,
"Monday"=> 1,
"Tuesday"=> 2,
"Wednesday"=>3,
"Thursday"=>4,
"Friday"=> 5,
"Saturday"=>6,
}
I store the integer in the database, but then when I display the integer it seems backwards that I have to create another map in order to go from integer->to->Saturday?
What am I doing wrong and how should I implement this correctly, soit is the dry principle?

If you want to adhere to the DRY principle, I recommend using Date::DAYNAMES.
E.g. like this:
<%= f.select :day_of_play, Date::DAYNAMES.each_with_index.collect { |day,i| [day,i] } %>

Related

Rails - Can you use collection_radio_buttons with options_for_select?

I currently have a select in a form which works fine:
<%= f.select(:scan_type, options_for_select(Scan::SCAN_TYPES, task.scan_type)) %>
I want to convert it to a set of radio buttons, as there are only a few options. Is there a way to use options_for_select with collection_radio_buttons?
I'm just using a simple array for my options, i.e. in scan.rb -
SCAN_TYPES = ['roll', 'single']
My first approach was to try
<%= f.collection_radio_buttons(:scan_type, options_for_select(Scan::SCAN_TYPES, object.scan_type)) %>
But I'm not providing all the arguments. I'm at a loss to see what needs to be added.
f.collection_radio_buttons(:scan_type, Scan::SCAN_TYPES.map{|s| [s, s] }, checked: f.object.scan_type)
Check this

Create Arrays for multiple Languages

I am searching for an easy way to create a select with multiple languages. Currently, I have used a HELPER to store an array with my SELECT options.
Helper
list = ["Book", "DVD", "Table", "Chair"]
CATEGORY = Hash[*list.collect { |v| [v, list.index(v)] }.flatten]
View
<%= f.select :category, options_for_select(ApplicationHelper::CATEGORY, selected: 0), { :class => "selectpicker" } %>
If there is a way to somehow use the LOCALE file this would be amazing too.
One solution would be to keep translations in the DB, You can search there are multiple gems available like language select
If you want to pull options from your translation YML files, I suggest options_for_select. All in all something like:
en.yml
en:
my_options:
0: "Book"
1: "DVD"
2: "Table"
3: "Chair"
View:
<%= f.select :category, options_for_select(t("my_options").invert, selected: 0), { :class => "selectpicker" } %>
Rails i18n gives you a hash if you translate a non-leaf key, like "my_options". You need the invert because options_for_select expects the text before the value, and a translation hash is the other way around.
You can explore more about it there are many way to do it this one is one of them and simple way.

Rails multiple drop down make it stick

I have created dropdown language selection list, however I would like to make it stick when user edits. I know that it can be done with the second argument of select_tag but could not do it.
I have a user model and associated language model;
<%= f.label :language, "Spoken Languages" %>
<br>
<%= select_tag("user[language_ids][]", options_for_select(Language.all.collect { |ff| [ff.name, ff.id] }, #user.languages.all.collect { |kk| [kk.name, kk.id] }),
{:multiple=>true, :class => "language_select form-control"}) %>
EDIT:
Here how it looks like, even though spoken languages are set before;
But it should look like with the pre selected languages (comes from database);
I used Select2 to create the dropdown list.
Try changing this part to: #user.languages.collect { |kk| kk.id }

select_tag doesn't save the selected option

I'm new in web development & Rails. I've been struggling to understand why my form is not getting saved completely. Here is the code I'm using:
<div class="field">
<%= f.label :type %><br>
<%= select_tag(:type, options_for_select([['Verb', 'Verb'], ['Adjective', 'Adjective'], ['Noun','Noun'],['Preposition','Preposition'],['Article','Article'],['Adverb','Adverb']])) %>
</div>
<div class="field">
<%= f.label :category %><br>
<%= select_tag "category",
"<option>Appliances</option>
<option>Clothes and Accessories</option>
<option>Colours</option>
<option>Communication and Technology</option>
<option>Documents and Texts</option>
<option>Education</option>
<option>Entertainment and Media</option>
<option>Family and Friends</option>
<option>Food and Drink</option>
<option>Health, Medicine and Exercise</option>
<option>Hobbies and Leisure</option>
<option>House and Home</option>
<option>Measurements</option>
<option>Personal Feelings, Opinions and Experiences (adjectives)</option>
<option>Places: Buildings</option>
<option>Places: Countryside</option>
<option>Places: Town and City</option>
<option>Services</option>
<option>Shopping</option>
<option>Sport</option>
<option>The Natural World</option>
<option>Time</option>
<option>Travel and Transport</option>
<option>Weather</option>
<option>Work and Jobs</option>".html_safe %>
</div>
PS: I've kept two different methods I tried to use.
use f.select instead of select_tag.
f.select(:type, [['Verb', 'Verb'], ['Adjective', 'Adjective'], ['Noun','Noun'],['Preposition','Preposition'],['Article','Article'],['Adverb','Adverb'])
or if you are using form_for and passing an object then you can also do it as follows.
select_tag(:type, options_for_select([['Verb', 'Verb'], ['Adjective', 'Adjective'], ['Noun','Noun'],['Preposition','Preposition'],['Article','Article'],['Adverb','Adverb']],f.object.type))
we are passing a value of type from actual object into option for select.
As you are using option_for_select it expects that you send selected value as a second parameter.
options_for_select also takes second parameter which is the selected value.
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select
# this will show Preposition selected
options_for_select([['Verb', 'Verb'], ['Adjective', 'Adjective'], ['Noun','Noun'],['Preposition','Preposition'],['Article','Article'],['Adverb','Adverb']], 'Preposition')
For future reference, please always specify Rails version while posting question.
I noticed you are using f.label, in which case you might also want to take a look at http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select
HTH
For the first one, you should use f.select instead of select_tag, rails tags are helpers for generate html elements, but in this case you need an item that is linked to your form, so you use the form helper for select instead.
For the other example, i'm not entearly sure if it will work like that, but try with the same idea, you should found that the select is passed to your controllers, also use the symbol name instead the string name, meaning :category instead "category", if you want to have a phrase like "select a category...." add another option at the end with :prompt => "select a category...", hope it helps and look at Ryan Bates site, is an excellent place to learn rails

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.

Resources