NoMethodError when returning an array in a form - ruby-on-rails

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'

Related

RoR collection_select does not work on array of hashes

- #variants[:options].each do |o|
= f.field_container :type do
= f.label :type, "TYPE"
= collection_select(o[:type_id], #types, :id, :name)
Hello! I have been trying to do this but I get an error undefined method map for :id:Symbol
#types = Type.all
and #variant[:options] looks like this
[{type_id: 1, type_name: "Color"},{type_id: 2, name: "Shade"}]
so the goal of my select is that, I would like to change the type_id inside the hash. any help?
UPDATE: so i tried this and it works but there is no selected value on the collection select.
= collection_select(o, o[:type_id], #types, :id, :name)

How do I search for multiple records in a search form?

I am trying to allow the user to be able to choose multiple records in a field on the search form.
Something like this:
<%= f.input_field :neighborhood_id, collection: Neighborhood.order(:name), :url => autocomplete_neighborhood_name_searches_path, :as => :autocomplete, 'data-delimiter' => ',', :multiple => true, :class => "span8" %>
It sends it to my search model like this: #search = Search.create!(params[:search])
This is what the Search.rb model does with it:
key = "%#{keywords}%"
listings = Listing.order(:headline)
listings = listings.includes(:neighborhood).where("listings.headline like ? or neighborhoods.name like ?", key, key) if keywords.present?
listings = listings.where(neighborhood_id: neighborhood_id) if neighborhood_id.present?
listings
The issue is that this is just accepting 1 neighborhood_id, so I am getting this error when I choose multiple objects:
undefined method `to_i' for ["Alley Park, Madison"]:Array
Where Alley Park and Madison are the names of 2 neighborhoods, not the IDs.
So how do I get this working?
Thanks.
Edit 1
The issue seems to not be in the lookup of the params[:search] per se, but rather in the conversion of the form input to an array of entries. I tried changing the search method to be something like:
listings = listings.includes(:neighborhood).where("neighborhoods.name like ?", neighborhood_id) if neighborhood_id.present?
Don't get hung up on the fact that I am looking up neighborhood.name and passing in neighborhood_id. I just did that because I know that the params for the field neighborhood_id were actually the names of the neighborhood. If this had worked, I would have refactored some stuff, but it didn't. So don't get hung up on that.
But that still returns the error undefined method 'to_i'....
Also, I still get that error even if I just pass in 1 option.
listings = listings.where("neighborhood_id in (?) ", neighborhood_id)
You can get the id instead of neighborhood names from the input field like this:
<%= f.input_field :neighborhood_id, collection: Neighborhood.order(:name), :url => autocomplete_neighborhood_name_searches_path, :as => :autocomplete, 'data-delimiter' => ',', :multiple => true, :class => "span8", :input_html => { :id => "neighborhood_id" } %>

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

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