How to set a child attribute as collection_select value? - ruby-on-rails

My form contains the following tag:
<%= f.collection_select :employee_id, #employees, :id, :value, :prompt => true %>
Employee looks like this:
employee
- attr1
- attr2
- user
- firstname
- lastname
My question: How to set the lastname of an employee as the value in the select field? I'm pretty sure it's possible, but I think I have some gaps in the syntax.

Why would you do that?
It's possible, with:
<%= f.collection_select :employee_id, #employees, :last_name, :text_method, :prompt => true %>
Where :text_method is method which called on #employees members will return text that you'd like to appear in dropdown.

You may be asking yourself why I have used <%= f.select %> this is FormOptionHelper on the Ruby on Rails Api this is very similar to collection_select however with that it returns and tags for the collection of values. Whereas select creates a series of contained option tags for provided object and method. So in saying this I believe you could have the following:
<%= f.select(:employee_id, Employee.all.collect { |emp| [emp.lastname, user.id] }
.sort{ |a, b| a[0] <=> b[0] }, {:prompt => "Select a Employee"}) %>
This selects all employees and sorts them in order of their last name.

Related

Getting value of an object in collection select

I have created drop down list for employees.
What I want?
I want to select full Name for each one of them.
Type of form:
I use simple_form.
I actually have:
= f.input :person_id, label: "Employee", collection: #employee, prompt: "Select employee"
Result(I know, that is reference):
Before I use collection_select, but simple_form doesn't support validation for this type of collection.
Code for collection_select. This type of drop down list displays properly full name.
= f.collection_select :person_id, #employee, :id, :fullName, {prompt: "Wybierz pracownika"}, {class: "form-control"}
Update:
fullName is a method in a person.rb model.
def fullName
"#{first_name} #{last_name}"
end
Object employee.
#employee = Person.where.not(type: "Client")
The easiest way to do this is :
= f.select :person_id, options_for_select(#employees.map{|e| [e.fullName, e.id]}), {:prompt=>"Wybierz pracownika", :required => true}
It will show full names as select options and will dispatch ids as values with form.
You follow this code like below:
<%= f.collection_select(:person_id, Model.all, :person_id, :fullName,{:prompt=>"Wybierz pracownika"}, {:class => 'form-control'}) %>
You will replace your model_name.
Or
= f.input :person_id, label: "Employee", collection: #employee.fullName, prompt: "Select employee"
I think will help you

HOw do I pre-select a value in my select menu if a cookie is set?

I’m using Rails 4.2.3. I have this select form field in my page …
<%= f.label :object %><br>
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}) %></div>
My question is, how do I pre-select a value if there is a cookie present named “object”? I would like to set the value of the select menu to be the value of the cookie. Note, I only want to pre-select the value if this view is served by my controller’s “index” action (The above is part of a partial view that is served by different controller methods).
Thanks, - Dave
Hey according to docs at APIdock:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:selected => current_book.authors.map(&:id)})
So You should write it like this:
In You controller specify you objects: #selected = cookies[:some_key]
collection_select(:user_object, :object, #objects, :id, :description, {:selected => #selected.map(&:id), :prompt => true})
You do not need whole objects, just the ids to check out selected ones. I think this should do the trick.
If you want some object to be selected by default, you can use :selected
assuming that your cookie object stores an id
{:selected => object}
<%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {:selected => object} ) %>
Get cookie value in your Index controller,
def index
#selected_object = cookies[:some_key]
end
In your Index.html.erb
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {selected: <%= #selected_object %> }) %></div>
Or you can get that cookie on the fly from View file,
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {selected: <%= cookies[:some_key] %> }) %></div>
Note that value of cookie might be hash, make sure you get the correct value, also you can use conditional in controller to avoid getting nil and resulting no value selected in view by,
def index
#selected_object = cookies[:some_key]
if #selected_object.nil?
#selected_object = "default_selected"
end
end
If you want some object to be selected by default, be sure to use its id, not the whole object.
Try the following:
<%= f.collection_select(:user_object,:object,#objects ,:id, :description,:selected => cookies[:object])%>
Note:
Make sure cookies[:object] returns an id of the items in the select list
Source - http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select#632--selected
I like to use options_for_select. Options for select can take an array or a two dimensional array, in the latter case the first value is shown to the user and the second value is what is saved. It can also take an optional second argument that selects the default value:
if cookies[:whatever_key_is]
<%= f.select(:object, options_for_select(["array", "of", "options"], cookies[:whatever_key_is]) %>
end
I usually write a method for passing the array, especially if it's two dimensional, and then call that method as the first argument. I actually also usually write a method for the second argument.

rails 4 -- concatenate fields in collection_select

I'm working on learning Rails 4 via several tutorials, and building a demo app.
I have a table called players that links to a team table. The team has many players, a player has only one team. So I'm using a collection_select tag to pull the team data into the player form.
It looks like this:
<%= collection_select :player, :team_id, Team.find(:all), :id, :name, options ={:prompt => "Select a team"} %>
This works fine-- but I'd like to have the format look like "Team Name: Team City"-- I can't figure out how to concatenate the :name and :city values in the tag however. Is this possible?
Create a method in your Team model like the following one
def name_with_city
"#{name}: #{city}"
end
Then use it as below
<%= collection_select :player, :team_id, Team.find(:all), :id, :name_with_city, {:prompt => "Select a team"} %>
Find out more about collection_select in the documentation
You can format the collection to your liking as:
<%= collection_select :player,
:team_id,
Team.find(:all).collect { |t| [ t.id, "#{t.name}: #{t.city}" ] },
:first,
:last,
{ prompt: "Select a team" } %>
The :id and :name parameters have been replaced with first and last signifying the value_method to be first and text_method to be last elements of each array.
If your form is looking up values based on parameters and you need those, the model method is not very convenient. Assuming your controller has a #searched_record method, you can do something like
<% #base_params = #searched_record.one_value << "=>" << #searched_record.second_value << "; " << (l(#searched_record.starts, :format => :long)) << ", " << #searched_record.other_value.description %>
<%= f.text_area :content, :rows => 5, value: #base_params %>

Multiple column names/custom label in Rails collection_check_boxes

I have a form_for in Rails that uses the collection_check_boxes method for an array of parts that get listed as check boxes. I want the label of the checkbox to be a composite of two methods so that each part's checkbox is labeled with it's name and it's SKU number:
my form code:
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :sku, {}, {checked: true}) %>
this works perfectly to create a list of check boxes. But each label is only the :sku since I can only pass it one method for the label. Does anyone know of a way to create a custom label for these? I have read the api docs and it mentions using a do |b| ... end block but doesn't explain how to use it or why.
Here is the modified form code:
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :sku, {}, {checked: true}) do |b|
b.label { b.check_box + b.object.name + " " + b.object.sku}
end %>
NOTE:
b.object.name #### Assuming that name is field name in your model
b.object.sku #### Replace with b.object.sku.to_s if sku is numeric field.
You could define a custom field in your model:
def cb_label
"#{name} #{sku}"
end
and in the collection
<%= collection_check_boxes(:service, :part_ids, #parts_list, :id, :cb_label, {}, {checked: true}) %>

How to use a table column in my select box on rails?

I'm trying to create a select box that takes data from my db. I'm having trouble setting this up. I tried this code:
<%= f.fields_for :unit do |u| %>
<%= u.label :name %>
<%= u.select :name, :class => "ingredient_unit", :prompt => "Please Select" %>
<% end %>
but I'm missing the part of the choices, I don't know how to pull them out of the database. I tried using collection_select, which worked, but then the class option wasn't working... collection_select went like this:
<%= u.collection_select :unit, Unit.all, :id, :name, :class => "ingredient_unit", :prompt => "Please Select" %>
I also don't understand what the first symbol means (:unit), it seems to be setting the html id and name, so that can be anything I want it to be?
You should look at the documentation for collection_select and select. But to answer your question, for the select part, you forgot to pass the list of options to choose from. You also need to swap the order for prompt and class since prompt is an option for the helper and class is an html option
<%= u.select :unit_id, Unit.all.map { |u| [u.name, u.id] }, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
For the collection select
<%= u.collection_select :unit_id, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
The first parameter passed to both helper is the column name where you want the selected answer to be saved. The 2 codes above just shows 2 different ways to generate the same select tag.
The first symbol tells it which field to populate with the id returned from the user selection.
Also, you should wrap your class section in {}
:unit refers to the model attribute that you're using for the select element. Yes, it will setup the name/id of the element (and name is the most important for the params hash).
To set a class in the collection_select, specify it as a hash as that helper takes it as an html_option.
<%= u.collection_select :unit, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>

Resources