Rails 3: select helper method default? - ruby-on-rails

I currently have this select helper call:
<%= f.select :macro_process_id, MacroProcess.all.collect { |mp| [mp.name, mp.id]} %>
How can i change this that if :macro_process_id has a value, then the selected element should be equal to that value?
If that makes any sense?
Thanks

Try
<%= f.select :macro_process_id, MacroProcess.all.collect { |mp| [mp.name, mp.id]}, MacroProcess.find(:macro_process_id) %>
The addition that I have made, will make it the default value selected among the other values.
For more info, look here: form-select-helper-in-ruby-on-rails

Related

Rails - Select tag not pre-selected after Form's validation fail

I have select tag
<%= f.select :gender, ["M", "F"], include_blank: "---" %>
If other field has error, the select tag will be reset to "---" even though I have picked an option before.
The solution that I found is using collection_select which takes a ActiveRecord Model to be the option-value pair.
Is there other way to do this?
Thanks
[EDIT]
The answer from #Micah is correct but since my form is Nested, it's different syntax.
Here's my code:
<%= f.fields_for :users do |ff| %>
...
<%= ff.select :gender, ["M", "F"], include_blank: "---",
selected: ff.object.gender ? ff.object.gender : "" %>
...
<% end %>
When I handle errors I usually use render to display the previous page again so I'm going to explain how to handle that first.
When you render a view the params that got passed into your previous command carry over, meaning you'll have params[:object][:gender]as a parameter when you return to the view. Thus
<%= f.select :gender, ["M", "F"], include_blank: "---", selected: params[:object] ? params[:object][:gender] :"" %>
will set the selected value back to what was selected the first time through. Basically what it's doing is taking a conditional and then providing an if/else in the same line. (conditional) ? if true do this : else do this. In this case the conditional is that params[:object] exists (meaning you've attempted to create/edit once before) and if so reassign value otherwise leave blank and select default value, your "---".
If you use redirect_to you'll actually have to manually pass the params back through the redirect but that's fairly simple and just takes the following:
redirect_to new_object_path(params)

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

How to make a check_box checked in rails?

I made checkboxes using the following rails form helper:
<%= check_box("tag", tag.id) %>
However, I need to make some of them checked by default. The rails documentation doesn't specify how to do this. Is there a way? How?
Here's how to do it as of rails 4, I didn't check older documentation.
<%= check_box("tag", tag.id, {checked: true}) %>
This will make the checkbox checked. Of course instead of true you will put in some logic which determines if each one is checked.
If you need the check_box to be checked on new, and correctly filled on edit you can do:
<%= f.check_box :subscribe, checked: #event.new_record? || f.object.subscribe? %>
As I mentioned here
The rails docs do say how to have it checked and it depends on the object. If you don't have an instance object to use with check_box, then your best option is to use the check_box_tag as mentioned. If you do, read on.
Here's the link to the docs on the check_box helper. Basically how this works is that you have to have an instance variable defined. That instance variable must have a method that returns an integer or a boolean. From the docs:
This object must be an instance object (#object) and not a local
object. It’s intended that method returns an integer and if that
integer is above zero, then the checkbox is checked.
For example, let's assume you have a #tag instance in your view which has an enabled method. The following snippet would cause the checkbox to be checked when enabled is true on the #tag object and unchecked when it is false. To have it enabled by default, set the enabled attribute to true in your controller. The last two variables are the values that you want to submit with the form when the check box is checked and unchecked.
<%= check_box "tag", "enabled", {}, "1", "0" %>
A lot of times, you'll see the check_box helper used with a form builder. So if form_for was used for the #tag instance, you would more than likely use this snippet:
<%= f.check_box :enabled %>
No need of writing checked: true for rails >= 4.0
Simply write
<%= check_box_tag "name", value, true %> # true or false
The check_box_tag instead of check_box has a way to set that it's been checked.
Using check_box_tag you can set it to true so that it's already checked. More info here: http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-check_box_tag
This answer is only related to f.check_box
f.check_box can take up to 4 arguments:
input name
hash containing options such as html class, id, etc
which value represents "checked" (defaults to "1")
which value represents "unchecked" (default to "0")
So if your boolean field is stored as either 1 or 0 (default for Rails) then everything is fine and well. Rails will recognize whether the field is checked or not.
However, if you're using a different data storage or a framework which is storing booleans in another format, you need to specify which values correspond to checked and unchecked.
Here's an example:
<%= f.check_box :accept_privacy_policy, { class: 'my-class' }, "true", "false" %>
References
https://api.rubyonrails.org/v6.0.0/classes/ActionView/Helpers/FormHelper.html#method-i-check_box
Problem with all of these solutions is that it doesn't play well with the params hash on resubmits, so at the moment I'm using something like this,
# ApplicationHelper
def resolve_boolean_parameter resource, attribute, options = {}
default = options.delete(:default)
return default unless params[:utf8]
return params[resource][attribute] == "1"
end
and then in the view:
<div><%= f.label :accepts_newsletter, "Receive Newsletters" %>
<%= f.check_box :accepts_newsletter, :checked => resolve_boolean_parameter(:user, :accepts_newsletter, default: true) %>
</div>
New Function placed in your Helper
def check_if_true(item)
ActiveModel::Type::Boolean.new.cast(item)
end
In your View
<%= check_box("test", "active", {checked: check_if_true(#test.active) , :multiple => true, :style => "margin-left: 16px;"}, "true", "false") %>
This is how I did this now in 2020.
<%= form.check_box :with_cost, checked: true, class: '', type: 'checkbox', id: 'cost' %>
With the checked: true attribute.
Hope this helps.
If you are using the form helper in Rails 5.1 + to build your checkbox you have to pass in a hash the values with specific order.
= form.check_box :open_after, { class: 'form-control mt-1', data: {}, checked: true }, true, false
As you can see, inside the hash, first is class, next data and last checked. This works for me with Rails 6.0

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.

collection_select set option value of :include_blank to zero

In my rails app, i have a drop down box where i retrieve all groups from the Group table and display them using the collection_select tag.
When the user selects 'None', I want to pass '0' as option value.
Currently, an empty string is passed.
Is there a way to include option value = 0 for 'None'?
<%= f.collection_select :SUB_GROUP, Group.all, :Group_ID, :Group_ID, :include_blank => 'None' %>
Many many thanks for any suggestion provided
If you use options_for_select in combination with select_tag you can achieve that using this:
options_for_select(
[['None', '0']].concat(
Group.all.collect { |g| [g.group_id.to_s, g.group_id.to_s] }
)
)
In order to keep your views uncluttered, you might want to generalize and move this into a helper method with a reasonable name.

Resources