Rails collection_select syntax - ruby-on-rails

I'm having issues with the following code:
= f.collection_select :ch_professional, #ch_professionals
I'm trying to set the ch_professional field with a select. #ch_professionals is an array of strings.
I'm getting the following error:
ActionView::Template::Error ({} is not a symbol)
I've looked for documentation on collection_select, and I haven't been able to find the correct syntax.

Signature for collection_select is
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
It expects the value_method and text_method to be symbols with method names that will be called to get corresponding values from each array element.
Error about {} is because of the way rails handles options hashes, it happened that default hash value of {} ended up in value_method.
So try something like:
= f.collection_select :ch_professional, #ch_professionals, :to_s, :to_s

Use the select form helper if you just have an array of strings and do not need to have different values for the value and text of the options e.g.
= f.select :ch_professional, #ch_professionals

Related

Simple form collection_radio_buttons show items from record model

I want to display all the available types in radio buttons in order to click and select on of them
= f.collection_radio_buttons :type_id, Type.all, :label => "Available Types"
but I'm getting the following error
wrong number of arguments (given 3, expected 4..6)
How can I fix the collection_radio_buttons in order to get the correct number of arguments?
Here is the api doc on collection_radio_buttons:
http://apidock.com/rails/v4.0.2/ActionView/Helpers/FormBuilder/collection_radio_buttons
it definitely indicates you need at least 4 arguments (minimum):
method, collection, value_method, text_method, options = {}
You have provided 3 - a method :type_id a collection Type.all
You've also provided options, but have missed the value_method and text_method That's what you need to add to make this work.
What method will be called on each Type for the text/values of the select-options? Usually this is something like: :id (for value_method) and something like :name (for text_method)

Error `undefined method `state' for "AK":String` for `collection_select`

After adding the second method, uniq.pluck(:state) to the code below, I'm getting the following error message:
undefined method `state' for "AK":String.
I looked at all the posts on here and couldn't find anything related to this problem. Any insights or help you could offer would be greatly appreciated.
<%= f.collection_select :state, (Boli.order(:state).uniq.pluck(:state)), :id, :state, include_blank: true %>
Thank you #D-side, now having difficulties using grouped_collection. I'd like the user to be able to select a group of banks in a particular state. Getting the error message undefined method `map' for :id:Symbol, using the following code:
<%= f.grouped_collection_select :bank, :id, Boli.order(:bank), :id, :bank, include_blank: true%>
pluck with a single attribute name returns an array of attribute values. Strings, in your case.
collection_select, however, is built with model instances in mind, in that it accepts... well, the docs say it better anyway:
collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
<...>
The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each <option> tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.
Obviously, since you've already fetched values of the attribute state, calling state on the resulting values once more is nonsensical.
You can fix this in multiple ways.
PostgreSQL's DISTINCT ON (expr)
By replacing .uniq.pluck(:state) with .select("DISTINCT ON (state) id, state") you'll get ActiveRecord model instances, so every element of the resulting collection will have methods id and state, as collection_select expects.
Or use the query you have, with pluck
...by giving procs instead of :id and :state that take a string as an argument and produce appropriate values.
It all boils down to what you need.

'Is not a symbol' error with collection radio buttons ruby

I am working on quiz app, and I can't use collection_radio_buttons for answer choices. I have a tests table.
`Question = test.question`, `choice A = test.answerA` and so on.
<%=
collection_radio_buttons(:test, test[:id], Test.all, :id, [[test.answerA], [test.answerB], [test.answerC], [test.answerD]], {})
%>
But this is giving me an error:
[["A) rasmiy"], ["B) ilmiy"], ["C) so'zlashuv"], ["D) badiiy"]]` is
not a symbol
Why is this happening?
The fifth argument for collection_radio_buttons is the text_method that is to be called on your collection. You are passing an array through this argument instead. The error message ... is not a symbol is telling you that the value that you're passing through that argument is an array, but it's expecting a symbol.
The method definition for collection_radio_buttons is:
collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
You probably want something like:
<%= collection_radio_buttons(:test, test_id, Test.all, :id, :name) %>
... where id and name are callable attributes on instances of whatever comes out of Test.all.
Source: http://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_radio_buttons

Ruby on Rails: combobox is showing id and not the name

I got the code
<%= f.select :wahl1, options_for_select(#berufs) %>
and im getting id´s or smth #<Beruf:0x45ed8e8> instead of the name of #berufs in the combobox
options_for_select expects a simple array or hash of keys and values. Yet you are passing it a collection of models.
What you want is options_from_collection_for_select, for example:
= f.select :wahl1, options_from_collection_for_select(#berufs, 'id', 'name')

Can someone explain collection_select to me in clear, simple terms?

I am going through the Rails API docs for collection_select and they are god-awful.
The heading is this:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
And this is the only sample code they give:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)
Can someone explain, using a simple association (say a User has_many Plans, and a Plan belongs to a User), what I want to use in the syntax and why?
Edit 1: Also, it would be awesome if you explained how it works inside a form_helper or a regular form. Imagine you are explaining this to a web developer that understands web development, but is 'relatively new' to Rails. How would you explain it?
collection_select(
:post, # field namespace
:author_id, # field name
# result of these two params will be: <select name="post[author_id]">...
# then you should specify some collection or array of rows.
# It can be Author.where(..).order(..) or something like that.
# In your example it is:
Author.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name_with_initial, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# <option value=#{author.id}>#{author.name_with_initial}</option>
# 'author' is an element in the collection or array
:prompt => true # then you can specify some params. You can find them in the docs.
)
Or your example can be represented as the following code:
<select name="post[author_id]">
<% Author.all.each do |author| %>
<option value="<%= author.id %>"><%= author.name_with_initial %></option>
<% end %>
</select>
This isn't documented in the FormBuilder, but in the FormOptionsHelper
I've spent quite some time on the permutations of the select tags myself.
collection_select builds a select tag from a collection of objects. Keeping this in mind,
object : Name of the object. This is used to generate the name of the tag, and is used to generate the selected value. This can be an actual object, or a symbol - in the latter case, the instance variable of that name is looked for in the binding of the ActionController (that is, :post looks for an instance var called #post in your controller.)
method : Name of the method. This is used to generate the name of the tag.. In other words, the attribute of the object you are trying to get from the select
collection : The collection of objects
value_method : For each object in the collection, this method is used for value
text_method : For each object in the collection, this method is used for display text
Optional Parameters:
options : Options that you can pass. These are documented here, under the heading Options.
html_options : Whatever is passed here, is simply added to the generated html tag. If you want to supply a class, id, or any other attribute, it goes here.
Your association could be written as:
collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })
With regards to using form_for, again in very simple terms, for all tags that come within the form_for, eg. f.text_field, you dont need to supply the first (object) parameter. This is taken from the form_for syntax.

Resources