Set Selected Value on Dropdown Based on Model Property - ruby-on-rails

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 } ) %>

Related

NoMethodError when returning an array in a form

I'm building an app for a restaurant and I have a form where I add meals to an order and a price field gets dynamically updated depending on what dishes and how many of them you pick.
To do that I built a nested form (I think that doesn't matter anyway) which looks as follows:
.nested-fields
= f.collection_select(0, #dishes.collect{ |dish| [dish.name, :data => {:description => dish.price}]}, :name, :name, {include_blank: true}, {class: "meal-select"})
= f.select :quantity, options_for_select((1..10))
= f.text_field(:price, disabled: true)
= link_to_remove_association "X", f
The thing that bugs me is the collection_select. As you can see, I am returning an array with a name and a data-description which goes to the HTML tag. Based on the data-description, my price field gets updated.
However, I have no idea what method I should choose to extract the name of a dish. As you can see I tried 0 since name of the dish is always first in the array. I have also tried :first, :name but none of those works! The error I get is:
"NoMethodError in Orders#new
undefined method '0' for #Meal:0x007fe4eb8e26c8"
or when I use :name
undefined method `name' for ["Zupa z Krewetkami", {:data=>
{:description=>17.0}}]:Array
Naturally, it points to:
= f.collection_select(0, #dishes.collect{ |dish| [dish.name, :data => {:description => dish.price}]}, :name, :name, {include_blank: true}, {class: "meal-select"})
I don't think the problem lies in my controller but, I'll show it just in case:
def new
#dishes = Dish.all
#order = current_user.orders.build
end
I tried looking for an answer here but as you can see the problem has not been solved and it was slightly different than mine.
To sum up - my question is what method I should use to extract name of the dish from my array in collection_select. Thanks!
Here is how you can use collection_select
...
= f.collection_select :meal_select, #dishes, :name, :price, {include_blank: true}, {class: "meal-select"}
...
For more details see the docs.
Use below approach
options_for_select( [['First', 1, {:'data-price' => 20}],
['Second', 2, {:'data-price' => 30}]] )
= f.select :meal_select, options_for_select(#dishes.collect{ |dish| [dish.name, dish.price,{'data-description' => dish.price}]}), :class => 'meal-select'

Set :selected value based on variableX -or- the user submitted value if variableX is nil

Have this select dropdown input field that is populated with state names.
I want to set the selected value to be the content of #state.id if this is not nil. If there is already a chosen option then I would like that to be selected instead.
How can this be done correctly? I tried several solution all of which fails, latest code example im using now:
= p.input :state,
:collection => ["State1","State2"]
:selected => (#state.id.to_s rescue nil) || (params[:state] rescue nil),
:id => "state",
:name => "state",
:prompt => t('forms.choose')
The problem is that the :selected option works based on two values.
The index of the element in the collection array, or
The value itself
So lets say you want the the last option to be selected, in your case you would need:
:selected => 1
or
:selected => "State2"
I hope it helps.

need to add default value in f.select field to existing ones - rails 3.2

With the code I have below in the select field I have all the public_campaigns:
<%= f.select :campaign_id, #public_campaigns.map{|x| [x.name,x.id]} %>
public_campaigns is defined in controller with:
#public_campaigns = #logged_in_user.campaigns.order('created_at desc')
In the form I select the campaign and fill up the rest of the form and at the submit action an invitation is created with campaign_id taken from the campaign I selected in the form, it can be anything from 1 to n
What I need now is to have a default item in select field that will have the value of 0 and named "No campaign", it means I invite someone to a campaign that I have not created yet and in invitation the campaign_id field will be 0.
Thank you for your time.
Do you really need 0? I think use of {:include_blank => "No campaign"} should be enough?
Try this:
<%= f.select :campaign_id, (#public_campaigns.map{|x| [x.name,x.id]} << ["No campaign",0]), {:selected => 0} %>
Well, the fastest way you can do this is something like this:
#public_campaigns = #logged_in_user.campaigns.order('created_at desc')
no_campaign = Campaign.new(:id => '0', :name => 'No Campaign')
#public_campaigns.unshift(no_campaign)
I'm not sure why you are unable to do it this way:
<%= f.collection_select :campaign_id, #public_campaigns, :id, :name, prompt: 'No campaign' %>
Just check if campaign_id.nil? instead of assigning any value to campaign_id

collection_select set option value of :include_blank to zero

In my rails app, i have a drop down box where i retrieve all groups from the Group table and display them using the collection_select tag.
When the user selects 'None', I want to pass '0' as option value.
Currently, an empty string is passed.
Is there a way to include option value = 0 for 'None'?
<%= f.collection_select :SUB_GROUP, Group.all, :Group_ID, :Group_ID, :include_blank => 'None' %>
Many many thanks for any suggestion provided
If you use options_for_select in combination with select_tag you can achieve that using this:
options_for_select(
[['None', '0']].concat(
Group.all.collect { |g| [g.group_id.to_s, g.group_id.to_s] }
)
)
In order to keep your views uncluttered, you might want to generalize and move this into a helper method with a reasonable name.

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