I am building a Rails app that tracks musicians. I want each user to be able to to select multiple genres they like from a form when they create a profile. I want to store it within the "profile" table for the user in the "genre" column. Right now, I have this, but it only allows me to select ONE option. I want the dropdown to allow multiple options. Is that possible? I'm sure this is very simple.
<%= simple_form_for #profile do |f| %>
<%= f.input :genre, collection:['Rock','Blues','Jazz','Classical','Soul','R&B','Alternative', 'Other'], label: "Favorite Genres" %>
Right now, genre is a string. Do I need to pass an array? How would I do that?
There are 2 things you need to do to handle a multi-select with rails.
1) Allowing the user to select multiple options on the form with the {:multiple => true} option.
<%= simple_form_for #profile do |f| %>
<%= f.input :genre, collection:['Rock','Blues','Jazz','Classical','Soul','R&B','Alternative', 'Other'], label: "Favorite Genres", input_html: {:multiple => true} %>
2) Let your controller accept an array of params for the value.
def profile_params
params.require(:profile).permit( :years_spent_playing, :user_id, :name, :bio, :age, :city, :state, :primary_instrument, :second_instrument, :third_instrument, :status, :looking_for, :image, :genre => [])
end
Im not sure your setup but I get the feeling you may not have the proper models and associations setup to handle this in the ideal way. I would suggest looking at adding a has_many :through association and breaking your genres out into a separate model and table.
Related
I have a Ruby on Rails application with some generated scaffold.
Now, in one of them I need to add a parameter that wasn't planned initially.
The situation is that I have two objects: Block and Keywords. The relationship between them is has_and_belongs_to_many. That allows me to have many keywords associated to many blocks and vice versa.
I want to add the option to add some keywords to the object Block during the creation.
I added the following code in the /views/blocks/_form.html.erb file:
<div class="field">
<%= f.label :keywords %><br>
<%= f.collection_select(:keywords, #keywords.order(:name), :id, :name, {include_blank: true}, {:multiple => true}) %>
</div>
I added the parameter in the controller as well:
def block_params
params.require(:block).permit(:name, :title, :description, :price, :instagram, :image, :main, :action, :keywords, :block_type_id, :module_keyword_id, :playlist_id)
end
Nevertheless I get this message in the log
Unpermitted parameter: keywords
and the keywords are not added to the block.
What am I missing?
When a parameter is an array, you have to permit it as an array with this:
def block_params
params.require(:block).permit(:name, :title, :description, :price, :instagram, :image, :main, :action, :block_type_id, :module_keyword_id, :playlist_id, :keywords, keywords: [])
end
note the "keywords: []", also note that I also left the ":keywords" key, that permits the param when you send an empty value too (en case you are removing all keywords for example).
What are the changes to be made in the controllers and the collection for accepting multiple values from a collection select.
The association between the models is:-
product has many categories through product_categories
categories has many products through product_categories
product_categories is the join table.
Below is my collection select, where i am using chosen to select multiple values.
<%= ps.collection_select :product_id, Product.all, :id, :product_name, {prompt: "Select Product"}, {class: "form-control chosen-select",:multiple => true}
Controller params
params[:spare].permit(:id, :name, :desc,:code,:manufacturer_id, :product_ids,{:attachments_attributes => [:id, :attachment, :remote_attachment_url, :_destroy]})
Also tried with nested attributes
params[:spare].permit(:id, :name, :desc,:code,:manufacturer_id,:product_ids,{manufacturer_service_centers_attributes: [:id, :service_center_id, :manufacturer_id, :_destroy]},{:attachments_attributes => [:id, :attachment, :remote_attachment_url, :_destroy]})
What changes should i do here for it to take product_ids? .
I was able to apply chosen multi select, These are the steps i followed.
with chosen select:
<%= f.select :product_ids, Product.all.collect { |u| [u.product_name_code, u.id] }, {}, {:multiple => true, :class => "chosen-select"} %>
Controller
params[:spare].permit(:id,:product_ids => [])
Hope it helps :)
Thanks :)
I'm using simple_form and I'd like to pre-populate several fields in my form. In the link to the form I'm passing several values to params in the URL. The trouble comes in when I either try to pass a value to a field that is an integer or an association. In either case, the field does not pre-populate.
Example below...the first two fields populate fine, but I had to force them to be text fields. Maybe that's ok to push the strings from the url into the field, but ideally I'd be able to use either the integer (f.input) or association (f.association). The second two fields don't pull in the param values from the URL.
Any ideas? Thanks in advance!
NOTE - this is for generating a NEW record in the database and not for editing an existing record.
URL: http://localhost:5000/list/new?event_id=4&user_id=11
<!-- These two fields pre-populate -->
<%= f.text_field :event_id, :value => params[:event_id] %>
<%= f.text_field :user_id, :value => params[:user_id] %>
<br>
<!-- These two fields do NOT pre-populate -->
<%= f.association :event_id, :value => params[:event_id] %>
<%= f.input :event_id, :value => params[:event_id], label: 'Event' %>
PS - I'm listening to GusGus' new album on Spotify while working on this and it's helping a lot. :)
Best practice is pre-populate form not with params directly but with ActiveRecord object.
For example you have an AR class:
class Party < ActiveRecord::Base
belongs_to :event
belongs_to :user
end
Then in your controller:
def new
#party = Party.new(party_params)
end
# use strong params to make your parameter more secure;)
def party_params
params.permit(:event_id, :user_id)
end
and then in your edit view:
<%= simple_form_for #party do |f| %>
<%= f.association :event %>
<%= f.association :user %>
<% end %>
I am creating a form has a drop down selection. I want to use two "text_method"s for the input but I am unsure how to do this. I want to include the year and name (both are two different columns in my rails model.
Here is what I have but it does not work:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year, :model_name, include_blank: true %>
Here is the official documentation- http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
Use this in your view:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Add a method like this to your Bat model:
def model_year_and_name
"#{model_year} #{model_name}"
end
I have players and fixtures that are in a HABTM relationship. This works well however when I am trying to add more that one player to the fixture using the following in my create new fixture view:
<li>Player 1<%= f.collection_select(:player_ids, Player.all, :id, :first_name, :prompt => true) %></li>
Only one player is submitted.
Controller
I have this at the moment in my fixture Controller
def create
#fixtures = Fixture.new(params[:fixture])
if #fixtures.save
flash[:notice] = "Fixture Created"
redirect_to(:action =>'list')
else
render('new')
end
end
View
<%=form_for(#fixtures, :url => {:action =>'create'}) do |f| %>
<li>Player 1<%= f.collection_select(:player_ids, Player.all, :id, :first_name, :prompt => true) %></li>
<li>Player 2<%= f.collection_select(:player_ids, Player.all, :id, :first_name, :prompt => true) %></li>
<li>Player 3<%= f.collection_select(:player_ids, Player.all, :id, :first_name, :prompt => true) %></li>
Could anyone help me out? I would prefer check boxes or a multiple select box where i could hold shift however I am finding these really hard to use. This I managed to submit values.
Thanks
If anyone needs any more informations on controllers or models I can edit these in to the quesiton
You need appropriate naming of fields. Each select must have name like fixture[player_ids][]
I doubt this is possible with #collection_select method, try more common #select_tag instead