Have a select box filled with names - ruby-on-rails

In my view I have a form with a text_field_tag that takes an int, and returns only the timesheets whose timesheet.user_id match that int
<%= text_field_tag("user_id", params[:user_id]) %>
And then I have a bunch of users, these users have a name user.name and an id user.id.
I have a method in the controller called pending_approvals that when given the user id, narrows my list down to a specific users objects.
if params[:user_id].present?
#time_sheets = #time_sheets.joins(:user).where("users.id IN (?)", params[:user_id])
end
So what I am having an issue with, is I am not sure how to populate my select box with a list of users names. And then when submitted I need it to give the users id to that method. What is the best way of doing this?

If I understand correctly is you want a collection dropdown list to detail all users and thier id. You can do:
<%= collection_select :user, :user_id, #users, :name, :id, :prompt => true %>
Where :text_method is method which called on #users members will return text that you'd like to appear in dropdown.
The ApiDocs breaks it down, and this is how it is set up:
object = User
method = user_id
collection #users
value_method = id
text_method = name
option = prompt => true

Related

How to set-up Rails form select for a collection

I'm working on a code base that I'm not very familiar with, specifically Haml. I need to set-up a select dropdown to select a user.
I have the following code in my controller:
def edit
#franchise = Franchise.find params[:id]
#ab_reps = User.where role: "admin-ab"
authorize! :update, #franchise
end
I have the following code in my form (that doesn't currently work):
= f.select :ab_rep, options_for_select(#ab_reps, f.object.ab_rep), {prompt: "AB Representative"}, {label: false, right_class: "col-sm-10", class: "ab-rep-field"}
Couple questions:
1.) #ab_reps is an array of user objects. I have the following method in my user model:
def name
[first_name, last_name].compact.join(" ")
end
How do I get the select to display the user names instead of the user objects (which it currently does) ?
2.) Is my current set-up even close to being correct?
Thanks for your help!
You are close, you need to provide the methods for the option value and the option text, as well as the collection which in your case is #ab_reps. Additionally you can provide a hash for prompts and for html_options such as class names, which you've done.
Rails has a few different helpers you can use for select tags including options_from_collection_for_select. I've used collection_select often, http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select
= f.collection_select :ab_rep, #ab_reps, :id, :name, {prompt: "AB Representative"}

Rails: how to get fields of rejected submit form?

I got one big form with many fields. There are multiple select_tag fields:
-(0..2).to_a.each do |id|
= select_tag('product[category_ids][]', options_from_collection_for_select(Category.all, :id, :name), :prompt=> '-- Select a Category --')
Problem: If the form is rejected upon submit, the :new action does not remember what is the previous selected values of select_tags.
Every other field reappears after submit (like :title, :description), but categories_id are lost.
Probable solution: We must add default selection to the select_tag in the options_from_collection_for_select method. How to get that category_id value? How can we access the fields of the previous form?
options_from_collection_for_select(Category.ordered, :id, :name, category_id)
You could store this data in the session and load it in the new action if it exists and clear that from the session.
That way anytime the fields reject the one that is not remembered loads into the session and is loaded into the select on the new action. Otherwise nothing is loaded when this session variable is blank.
Hope this helps.
In my form
#product.categories = []
but
#product.category_ids = [1,42,57]
So I added one messy if statement:
-if #product.category_ids.count == 0 #create new product
-(0..2).to_a.each do |id|
= select_tag('product[category_ids][]', options_from_collection_for_select(Category.all, :id, :name), :prompt=> '-- Select a Category --')
-else #edit old product, or fixing errors to previous submit
-#product.category_ids.each do |category_id|
= select_tag('product[category_ids][]', options_from_collection_for_select(Category.all, :id, :name, category_id), :prompt=> '-- Select a Category --')

Rails Form_For Select With Dual Purpose

I have form for adding a new job. On my form I have a select drop-down list. I need to associate the new job to a customer. The following works great.
<%= f.collection_select :customer_id, Customer.all, :id, :business_name %>
But, what if I want to also be able to send in a customer_id to the new form? Can I have the form's select drop-down show all the possible customers, as above, but have it auto select the customer_id I pass into the form, if a customer_id is passed in?
url = ...jobs/new
OR
url = ...jobs/new?customer_id=5
I apologize if I did not explain this well enough.
Thanks in advance.
--jc
I think you do what you're trying to achieve this by populating the customer_id field on the job you're creating in your controller if customer_id is present in the request params. This should make that particular customer be the initially selected option in the form.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
e.g. Something like.
if params[:customer_id].present?
job.customer_id = params[:customer_id]
end
If you declaring the instance variable #customer in your controller action then you can use selected option as:
<%= f.collection_select :customer_id, Customer.all, :id, :business_name, {:selected => #customer.id} %>

ruby on rails how to use FormOptionHelpers to create dynamic drop down list

I have checked some tutorials but I got confused by the parameters in this method
collection_select (object, attribute, collection, value_method, text_method, options = {}, html_options ={})
I have a map model includes: :area, :system, :file
and I want to read :area from database to a drop down list, and let user choose one
I already did #map = Map.all in the view
what the method should be?
especially the parameter "attribute". In a lot tutorials, people put "id" here. But I don't know what "id" is, and in my situation I don't need any other value, just the "area".
Im not exactly sure what you are asking here but if you are trying to make a dropdown selection for use in an html form will this example help you at all?
<% nations = {'United States of America' => 'USA', 'Canada' => 'Canada', 'Mexico' => 'Mexico', 'United Kingdom'=> 'UK'} %>
<% list = nations.sort %>
<%= f.select :country, list, %>
Here nations is a hash of countries then list becomes the sorted copy of that hash. An html dropdown is then created as a part of the form "f". ":country" is the part of the model that the data is connected to while list is the options to populate the dropdown with
It's not clear from your question what the model is that's being populated with the area.
Typically, collection_select is used between related models.
eg.
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :category
end
When selecting the 'category' for a product, your view would have something like:
<%= f.collection_select(:category_id, :id, Category.all, :name, include_blank: true) %>
What this does is specify the Product.category_id as the attribute being populated with the value of Category.id. The values come from the Category.all collection, and with Category.name being the item displayed in the select. The last (optional) parameter says to include a blank entry.
Something like the following is probably what you need:
<%= f.collection_select(:map_id, :id, #map, :area) %>
However, if the model you're trying to populate has an area attribute (instead of an ID linking to the map), you might need to use:
<%= f.collection_select(:area, :area, #map, :area) %>
This specifies that the area attribute of the receiving table will be populated with Map's area attribute, which is also being used as the "description" in the select.

How to send user.id with :user in params even though user.name is what is in the form drop down?

Currently, I have an action in my customers controller generating an array of names, #username_array, of all objects of class User with which to populate a drop down menu in a form that creates a new object of class Customer. The form element looks like this right now:
<%= f.select :user_id, #username_array %>
What I'd really like is for the id of the user to be sent into params[:customer][:user_id] instead of the name of that user that is chosen in the drop down. So in my create action in my customers controller I have the following code:
#customer = Customer.new(params[:customer])
#user = User.find_by_name(params[:customer][:user_id]) # where :user_id is actually currently the name selected from the drop down
#customer.user_id = #user.id
Is there an easier way of doing this?
Change your #username_array to include both the name and the id of the user:
Instead of:
["Bob","Sally","Dave"]
Make it:
[["Bob", 1],["Sally",2],["Dave",3]]
This could be accomplished by something like this:
#username_array = User.all.map {|user| [user.name, user.id]}
Then, f.select will display the name in the dropdown, but the actual value passed in through params[:customer][:user_id] will be the id of the user, which is what you want. With this in place, the following is all you need in the controller action code:
#customer = Customer.new(params[:customer])
You won't have to look up the user by name, the params hash will already have the correct id value.
Note that instead of making #username_array an instance variable you could just create a utility method in the helper for this controller, or the application helper:
def user_select
User.all.map {|user| [user.name, user.id]}
end
Then, in your view:
<%= f.select :user_id, user_select %>
If you put this in your application helper, you can use it everywhere and only have the code in one place (DRY).
you can do
#user = User.find_by_name(params[:customer][:user_id])
#user.customers.new(params[:customer])
or
#user = User.find_by_name(params[:customer][:user_id])
#customer = #user.customers.create(params[:customer])
but to do that you must have the relation (has_many, belongs_to,...)
or
Customer.new(params[:customer], :user_id => params[:customer][:user_id])
or
f.collection_select :user_id, #username_array, :id, :name

Resources