Rails select helper - set default? - ruby-on-rails

Rails 2.3.11
I did read this answer, but it's not working for me.
I would like the default option for this selection box to be the event_id passed through the URL.
f.select :event_id, #events, :selected => url_args["event_id"]
An example #events is[["SC 2 Tournament", 195], ["Obstacle Course", 196], ["Mortal Combat", 197]]
The following also didn't work:
adding ".to_i" to "url_args["event_id"
using options_for_select(#events, url_args["event_id"]
Thank you!

This is a lot easier if you use the collection_select helper:
f.collection_select :event_id, #events, :id, :name
Then to select the default option (and have that be selected on pageload), you can simply assign it to whatever Object it is that the form is for within the controller. eg like this:
def new
#events = Event.all
#thing = Thing.new(:event => #events.first)
end
I'm not sure where your url_args comes from, but I'm guessing it's probably from a param in the URL, in which case you can do this:
Thing.new(:event_id => params[:event_id])
One last thing - collection_select won't quite work with #events as you've specified it, as you're using a nested Array, when it's expecting an Array of Objects that it can call id and name on in order to retrieve the values and display text for the select options. To fix that, simply redefine #events within your controller, using one of the ActiveRecord finders, such as Event.all or Event.find(..).
Make sense?

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"}

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.

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.

rails bringing back all checkboxes instead of only selected one

I am using simple_form and have a following sample tag:
<%= f.input :medical_conditions, :label=>false, :collection => medical_conditons, :as => :check_boxes%>
The collection holds about 100 checkboxes. However, when user only selects 1 or 2, everything is still getting saved to the database like this:
---
- ""
- ""
- ""
medical_conditions is a simple array in my application_helper
def medical_conditons
t = [
"Allergies/Hay Fever",
"Diabetes",
"Heart Surgery"]
return t
end
the medical_conditions field is a :string field.
What do I need to do so that only values that are selected are saved in comma separated manner.
It is not simple_form behavior. It is from Rails. See this: http://d.pr/6O2S
Try something like this in your controller (guessing at how you wrote your create/update methods)...
params[:medical_conditions].delete('') #this will remove the empty strings
#instance.update_attribute(:medical_conditions, params[:medical_conditions].join(','))
#or however you want to save the input, but the key is the .join(',') which will
#create a comma-separated string of only the selected values, which is exactly
#what you're looking for me thinks :-)
If that does the trick for you, I'd consider making a private helper method that formats the params for you so that you can use it in #create, #update, or wherever else you need it. This should keep things a little cleaner and more "rails way-ish" in your crud actions.

ActiveScaffold: How do I set the default value for a drop down list?

So I have this create form to create schedules where there is a bunch of fields and one of them is seasons. And seasons table has a field called 'is_current' which if set to 1 tells us that it is the current season. When the create form is display , I want the current season to be selected by default in the seasons drop down. Any help will be appreciated. Thanks.
You can use the :selected attribute in the select form method, though this will expect the value of the option tag. Let's make a simple dropdown that has the ID of the season as the option value, the name of the season as what the user sees and a specific record selected by default, like this:
<option value="123" selected="selected">Name of season</option>
<option value="234">Another season</option>
In this case, the :selected attribute will expect 123, so that it knows to make it the default value.
You can accomplish that with the following code:
Controller:
#seasons = Season.all
#current_season = #seasons.detect{|s| s.is_current == 1}.id
View (in a form_for statement):
<%= f.select :season_id, #seasons.collect {|s| [s.name, s.id]}, :selected => #current_season %>
I believe it would be something like
#controller
#seasons = Season.all
#current_season = seasons.detect{ |s| s.is_current==true }
#view
select('schedule', 'season_id', #seasons.collect{ |s| [s.name, s.id] },
:selected => #current_season)
Edit
Sorry for the misunderstanding... I would try something like the following:
Create a named_scope on Season model
named_scope :current, :conditions => "is_current = true"
and try to set up this option
config.columns[:seasons].options = {:selected => Season.current}
I don't know if it works. It's just a shot.
I found the solution. You have to add a piece of code in the appropriate helper file, in my case the schedules_helper.rb.
def seasons_list
s = Season.find(:all, :order => 'is_current DESC').map{|t| [t.name, t.id]}
end
This will make sure the current season is always the first option of the drop down and hence by default is selected.
Thanks all, for your answers.

Resources