haml select_tag with constants - ruby-on-rails

I'm new to Ruby and Haml, so I"m going around in circles on this. Googling isn't giving me any sample code I can use.
I can use the select_tag and populate the list from a table. But I can't figure out how to use a simple static list of items. Can someone change this to be proper Haml? Note: the source table is 'email' and the field is 'status'.
= select_tag(:email, :status, {"canceled", "pending", "success"})
I'm looking to get a dropdown list that just has the items "canceled, pending, success" in it.
The error I get is odd number list for Hash._hamlout.format_script...
Update: I found some sample code that seemed to be what I need, and it doesn't give any errors, but the dropdown box is empty:
= select_tag(:email, :status,{ "canceled" => "1", "pending" => "2", "success"=>"3"})
Here is the HTML it produces:
<select female="2" male="1" id="email" name="email">status </select >

You are using the tag helper rather than the object-oriented helper. Use select
I'd also recommend using options_for_select. Like so:
= select(:email, :status, options_for_select([["canceled", "1"], ["pending", "2"], ["success", "3"]]))
See:
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select

Got it working! I need to use "Select" instead of "Select_tag". :-)
= select(:email, :status,{ "canceled" => "canceled", "pending" => "pending", "success"=>"success"})

Related

Ruby Hash is including extra values for a single key

I've tried to build a hash multiple ways, but when I use it in a grouped_options_for_select tag, there are extra values that aren't in my original hash. Here are two ways I've tried to build my hash:
UNITS_OF_MEASURE_GROUPED = {
"Dry" => ["oz", "lb", "g", "kg"],
"Liquid" => ["floz", "gal", "ml", "L"],
"Other" => ["each"]
}.freeze
and a bit more explicit and very wordy:
UNITS_OF_MEASURE_GROUPED = {}
UNITS_OF_MEASURE_GROUPED[:dry] = ["oz", "lb", "g", "kg"]
UNITS_OF_MEASURE_GROUPED[:liquid] = ["floz", "gal", "ml", "L"]
UNITS_OF_MEASURE_GROUPED[:other] = ["each"]
UNITS_OF_MEASURE_GROUPED.freeze
But the grouped_options_for_select always includes "floz" and "each" in the first section ("dry"). Please see attached image.
I forgot to add my form element code:
<%= form.select :unit_of_measure, grouped_options_for_select(UNITS_OF_MEASURE_GROUPED) %>
As per Guiseppe in another comment, I tried <%= form.select :unit_of_measure, UNITS_OF_MEASURE_GROUPED %> with the same result.
Something that does seem really weird is when I go into the console after triggering an error, my UNITS_OF_MEASURE_GROUPED hash shows this:
{:dry=>["oz", "lb", "g", "kg", ["floz", "gal", "ml", "L"], ["each"]], :liquid=>["floz", "gal", "ml", "L"], :other=>["each"]}
My guess is that's screwing up the HTML and getting confused. Does that help?
What am I missing? Thank you SO much in advance.
I'd be inclined to concur with the suspicion that something mangling your hash is to blame. To find out what, try a deeper freeze:
UNITS_OF_MEASURE_GROUPED = {
dry: %w(oz lb g kg),
liquid: %w(floz gal ml L),
other: %w(each)
}.transform_values(&:freeze).freeze
This'll (hopefully) throw a FrozenError, and accompanying illuminating stack trace, from wherever deep in the app/framework is screwing with it.
The problem is the way you are calling form.select inside the erb tag.
You are supposed to pass a collection but instead, you are passing a string as the second argument.
You should pass UNITS_OF_MEASURE_GROUPED instead of grouped_options_for_select(UNITS_OF_MEASURE_GROUPED) as in the following example:
<%= form.select :unit_of_measure, UNITS_OF_MEASURE_GROUPED %>.
If you look at rails guides you can find an example.
The select helper
Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:
ActionView::Helpers::FormOptionsHelper#select requires a collection as parameter.
Edited.
It could be the generetion of hidden fileds that you get by default
Try the following
<%= form.select :unit_of_measure, UNITS_OF_MEASURE_GROUPED, {include_hidden: false} %>
See Documentation for details.

How to set the value of a string field using a checkbox?

In a Rails app I have a model with a string attribute, that can only accept a short list of possible values.
A gender select is a good example of this:
(using simpleform)
<%= f.input :gender, :collection => [["male"],["female"]], :prompt => "Select" %>
and provides three states, 'male', 'female', and unselected.
In an effort to improve UX, we're replacing this select field with two checkboxes with values of 'male' and 'female', which again provides three options due to some jquery magic.
male / false
false / female
false / false
The problem is, the value of the first checkbox is alway overwritten by the value of the second on form submit.
Now I could do something with jquery on the client side to deal with this, I could also create a method on the server to deal with this. But that is not the purpose of this question.
I've never been confident that I fully understand all of the various features and uses of f.check_box, check_box object and check_box_tag. Is there a clever way to achieve the desired result within a Rails form, or am I on the wrong track?

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.

Read from params[] in Rails

I use:
<%= select( "payment", "id", { "Visa" => "1", "Mastercard" => "2"}) %>
and I get this in HTML
<select id="payment_id" name="payment[id]"><option value="2">Mastercard</option>
<option value="1">Visa</option></select>
now how can I read the payment[id] with params[], if I use params[payment[id]] I get an error.
I suppose is better to have
params[:payment][:id]
Params is a hash and can be contain some other hash.
This one had me stumbled for a couple of hours when I first started with ruby/rails. In your controller and views you can access the payment's id with either:
params[:payment][:id]
or...
params['payment']['id']
Many people prefer using symbols (:symbol) over strings because of memory usage, no matter how small the gains...
params[:payment][:id] and params[:payment][:id] is the same on surface ,
but in fact , in ruby ,you can't access the payment's id with params[:payment][:id].
because rails has changed the usage of it.

Reusing the partials multiple times on one page in Ruby on Rails

I have a partial that renders a select box using the following method:
<%= collection_select 'type', 'id', #types, "id", "name",
{:prompt => true},
{:onchange =>
remote_function(
:loading => "Form.Element.disable('go_button')",
:url => '/sfc/criteria/services',
:with => "'type_id=' + encodeURIComponent(value) + '&use_wizard=#{use_wizard}'"),
:class => "hosp_select_buttons"
} %>
This partial gets used 2 times on every page, but at one point I need to get the value of the first select box. Using:
$('type_id')
returns the second select box. Is there a way to find the first one easily? Should I fix this using javascript or by redoing my partial?
Note: the dropdowns do get rendered in separate forms.
Yes, each element does need a unique ID, the page probably also fails HTML validation. Also, unless these are in 2 different forms you'll have a conflict with the CGI parameter name.
If they are in 2 different forms you can probably get away with just setting the :id as you posted, if they are the same form you need to abstract the parameter name too:
collection_select 'type', "id_wizard_#{use_wizard}"...
I figured out one way to do this by assigning an ID in the html_options block. I already am passing in a value for use_wizard, so I can append that value on to the ID to differentiate between the two dropdowns.
:id => "type_id_wizard_#{use_wizard}"

Resources