options_for_select selected value not working - ruby-on-rails

I have a form for projectuser data, but when I edit the projectuser, the selected projectuser stays empty, what is going wrong? This is the code:
= f.select :user_id, options_for_select(#users.map{ |u| [u.full_name, u.id] }, selected: #projectuser.full_name), include_blank: true

The documentation states:
(...)
options_for_select(container, selected = nil) public
(...)
(million examples)
So you shouldn't pass selected: something, but just something. Also, this something needs to be selected value, not text:
= f.select :user_id, options_for_select(#users.pluck(:name, :id), #projectuser.id), include_blank: true

following your answer I wrote something like this.
f.select :relationship,
options_for_select(
Relationship.all.map{|rel| [rel.name, rel.id]},
#order.relationship.id.to_s ),
prompt: 'Please select', class: "form-control"
I get an Called id on nil error as this is trying to set a selected value which doesn't exist yet.
I'm on rails 3.13
my Order model has a belongs_to relationship with the Relationship model
Thanks for your help.

Related

Unpermitted params customer_ids

Super simple, dumb thing, which I can't figure out for more, than an hour now:
def user_params
params.require(:user).permit(customer_ids: []) # pg array column
end
My form:
= f.select :customer_ids,
options_from_collection_for_select(customers, 'id', 'name', user.customer_ids),
{ include_blank: 'Select customer', multiple: true, size: 15 },
class: 'form-control'
And while updating user I'm getting
Unpermitted parameter: customer_ids
How the heck in the world is that possible?
Parameters: {"utf8"=>"✓", "authenticity_token"=>"oCkUEi2pNajM0ydHUH2w6iYIq5eKjfCY5ig9U2qDTXxMqECCgQ2Dn9YtqkMqXlTmLl5q/OO8x23o/P50SnmgUg==", "user"=>{"customer_ids"=>"84"}, "commit"=>"Assign selected customer to user", "id"=>"2"}
Your form isn't sending in the customer_ids parameters as an array.
"user"=>{"customer_ids"=>"84"}
This is why. It should be (notice the square brackets):
"user"=>{"customer_ids"=>"[84]"}
If you declare the param as an array, it should be posted as an array. This is likely an issue in your form.
Usually, I would use checkboxes for something like this, but this depends on your user interface. Here's something similar I have done in the past.
= f.collection_check_boxes :customers, customers, :id, :name do |cb|
= cb.label
span.pull-right = cb.check_box
Look at the collection form helpers in Rails. A multiselect should work, but I have not used one this way.
Try changing your select tag like this
= f.select(:customer_ids, customers.collect { |c| [ c.name, c.id ] },
{ prompt: "Select Customer"},
{ multiple: true, size: 5, class: 'form-control' })

Combining elements in select dropdown while maintaining correct id in association

So I have a dropdown where I want it to look like this so that they can see the fullname. However when this is done it always puts student_id as 0 in my join table.
= f.association :student, as: :select, label: false, input_html: {class: "form-control" },
prompt: "Select a Student", collection: Student.all.map{|s| "#{s.firstname} #{s.lastname}"}
To get it to work I have to remove the collection: ...
Is there another way to get it, such as setting value to id?
I figured it out. All I had to do is add a array inside the collection block with the first item displayed and the second item as the id. So it should look like this:
collection: Student.all.map{|s| ["#{s.firstname} #{s.lastname}",s.id] }

Validates the presence of an option

I have a form that I want to validate if an option has been selected.
I do not want to accept the default starting option, "Please Select a Product"
I using this now and get a uninitialized contant error. I believe I am writing the syntax wrong.
Controller:
validates :product_name, :presence => { :unless => (product_name = "Please Select a Product")}
View:
<span class="span5 pagination-right">
<%= f.label "Product" %>
<%= f.select :product_name, options_for_select([ ["Please Select a Product"] ]) %>
</span>
How am I supposed to have the option written?
Thank you
The product_name is changed like this:
<script>
$(document).ready(function() {
$('#ticket_product_name').html("<option>Please Select a Product</option>");
$('#ticket_firmware_version_string').html("<option>Please Select a Firmware</option>");
$('#category').change(function(){
$('#ticket_product_name').html("<option>Please Select a Product</option>");
$('#ticket_firmware_version_string').html("<option>Please Select a Firmware</option>");
if ($('#category').val() == "blah")
{
$('#ticket_product_name').append("<option>blah</option>");
$('#ticket_product_name').append("<option>blah</option>");
}
else if ($('#category').val() == "another category")
{
$('#ticket_product_name').append("<option>blah product</option>");
}
until end of options, end script.
I think what you are looking for is a placeholder for this select. In this case, I used a disabled option:
<% options = options_for_select(["Select an option", ["Product #1",1], ["Product #2",2]], disabled: "Select an option") %>
<%= f.select :product_name, options %>
You should use include_blank from the select helper, like this:
<%= f.select :product_name, options_for_select([["opt1",1],["opt2",2]]), include_blank: true %>
and then, on model
validates :product_name, :presence => true
#MrYoshiji commented something truthful in my answer - if you are not allowing it to be blank, the easy way is simply not add a blank option in the select
I would recommend to use the :prompt option for your select helper (the documentation on this isn't quite straight forwward, but it's ok in this version of the same thing: http://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag). This allows you to define a helper string of text to encourage the user to select an option, but will submit a nil value back when the form is submitted.
<%= f.select :product_name, PRODUCT_NAME_OPTIONS, prompt: 'Select an option' %>
The next thing I'd recommend is... instead of validating presence of on the model, do a validates_inclusion_of. This way you can define the set of options in the model and then use that same set of options in the select helper, above, as well is in your validation. This way you know the form wasn't manipulated to include a different option and it actually keeps things a bit DRYer.
Product
PRODUCT_NAME_OPTIONS = {'opt 1' => 'opt1', 'opt 2' => 'opt2'}
validates_inclusion_of :product_name, :in => PRODUCT_NAME_OPTIONS.values, :message => 'choose from the available options'
Instead of making this too complicated, I just added a length validation since the default is much longer then the product names. Simple is best, however there should be a string validator option.
validates :product_name, presence: true, length: {
maximum: 21,
too_long: ": Must select a product"
}

Set Selected Value on Dropdown Based on Model Property

i have a simple dropdown like :
<%= collection_select("user_cities", "city_id", current_user.cities, :id, :name ) %>
current_user.cities is an array of the user cities. Each city has a field named "is_primary" and only one city has it set as true.
My question is, how can i make the above collection_select(or transform it if needed), so that it picks the selected option, based on City.is_primary ?
From the docs:
By default, post.person_id [in your case user_cities.city_id] is the selected option. Specify :selected => value to use a different selection or :selected => nil to leave all options unselected.
Armed with that knowledge we can pass the appropriate option to collection_select:
<%= collection_select "user_cities", "city_id", current_user.cities, :id, :name,
:selected => current_user.cities.detect(&:is_primary).id
%>
collection_select("user_cities", "city_id", current_user.cities, :id, :name,{:selected => current_user.cities.where(:is_primary => 1)})
I would start by defining a method called primary_city in your User model.
def primary_city
cities.where(:is_primary => true).first
end
Then,
<%= collection_select("user_cities", "city_id", current_user.cities, :id, :name, { :selected=> current_user.primary_city.id } ) %>

Not setting anything in Rails' collection_select

I have a Rails 2.3 web application that uses the collection_select helper with :multiple => true to handle a habtm relationship. This is working fine to set one or multiple values, however I have not figured out how to allow to REMOVE all selections.
Code:
<%= f.collection_select :category_ids, Category.find(:all), :id, :name,
{ :selected => #entry.category_ids },
{ :multiple => true, :name => 'entry[category_ids][]' }
%>
Once the user has ever set a category for an entry, how would I go about allowing it to be removed, so that this entry has no category? Is this possible with collection_select or would I need to add a checkbox to handle this specially?
P.S: I already tried with :prompt, :include_blank and :allow_blank, but as far as I could see neither of them did anything.
In your controller's update action, put in the following line:
params[:entry][:category_ids] ||= []
before the call to Entry.find.

Resources