I'm trying to create a drop down menu to allow a user to change an entry's field in my table. The user has one of three options -- hot, medium and cold.
I already have text_fields that do essentially the same thing for other fields, that all update when the user clicks on a submit_tag.
Is there an easy way to implement a drop-down box and have the result saved with the submit_tag ?
thanks,
-Chris
Here's the basic answer. The array of two element arrays is the critical part.
<% form_for #entry do |f| %>
<%= f.text_field :name %>
<%= f.select :temperature, [['Hot','hot'],['Medium','medium'],['Cold','cold']] %>
<%= f.submit %>
<% end %>
I'll assume 2 things:
That you are the <%= form_for #model_instance idiom (explained on section 2.2 of this guide).
That you want to store the "hot", "medium" and "cold" values as strings (not as numbers 1,2 and 3 or something similar) on your database.
Let's say that you have two fields, called :name and :temperature, controlled by two text_fields:
<% form_for #article do |f| %>
<%= f.text_field :name %>
<%= f.text_field :temperature %>
<%= f.submit "Create" %> <% end %>
<% end %>
Now you want to change the :temperature control to a dropdown list, accepting hot, medium and cold as values. Then you can do that this way:
<% form_for #article do |f| %>
<%= f.text_field :name %>
<%= f.collection_select :temperature, Article::TEMPERATURES, :to_s, :to_s,
:include_blank => true
%>
<%= f.submit "Create" %> <% end %>
<% end %>
You will now have to define the Article::TEMPERATURES constant in your Article model. It shouldn't be very difficult:
class Article < Activerecord::Base
TEMPERATURES = ['hot', 'medium', 'cold']
You may be wondering why I added the :include_blank part on the collection_select. This will add an "empty" option on your dropdown list. You will need that empty option when creating new objects, unless you want a "default" value to temperature.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#M001730
I was working on something similar. I got this to work by simply adding either an enum or a constant(similar to what kikito said previously) in my model and then calling the select in my form.
Here's how it can work.
using the constant:
class ClassName < ActiveRecord::Base
TEMPERATURES = ['Hot', 'Medium', 'Cold']
end
bin/rails g migration add_column_to_table temperatures:string
_form.html.erb
<%= f.label :temperature %>
<%= f.select :temperature, ClassName::TEMPERATURE %>
or
using the enum:
class ClassName < ActiveRecord::Base
enum temperature: [:hot, :medium, :cold]
end
bin/rails g migration add_column_to_table temperatures:integer
_form.html.erb
<%= f.label :temperature %>
<%= f.select :temperature, ClassName.temperatures.keys %>
Hope that helps you!
You might want to consider formtastic gem which is lot less code.
<% semantic_form_for #stuff do |f| %>
<% f.inputs do %>
<%= f.input :name %>
<%= f.input :temperature, :as => :select,
:label => "Degree", :include_blank => false,
:collection => [["Hot", 1], ["Medium", 2], ["Cold", 3]] %>
<% end %>
<%= f.buttons %>
<% end %>
In accordance with all of the above answers, remember to do this last, important step:
Restart your server!
As a newbie, I was wondering why my array was not working even though I followed all the steps correctly.
Related
I am having some difficulty to figure out why the post data from the form is not posted correctly.
I have to models: Child and Parent
in the form of Child i am nesting a form of Parent in this way:
<%
parent = (child.parent) ? parent : Parent.new
%>
<%=f.fields_for :parent, parent do |builder| %>
<%= render 'parent_fields', :fp => builder %>
<% end %>
The parent_fields form is as follows:
<% #all_parents = Parent.all %>
<% parent = fp.object %>
<%= fp.fields_for :parent do |builder| %>
<%= builder.input :parent_id, :as => :select, :label => 'Parent: ', :required => false,
:collection => options_from_collection_for_select(#all_parents, "id", "name", parent.id), :include_blank => '- Select -' %>
<% end %>
The posted data hash shows as follows:
"parent_attributes"=>{"parent"=>{"parent_id"=>"6"}, "id"=>"36"}
where 36 is the old parent id and 6 is the new one.
When i do update_attributes it does not work which is normal because it would work if the hash would be like this way:
...
"parent_id" => 6
"parent_attributes"=>{"id"=>"36", ....}
...
I am working on a legacy code. It is also possible that data was modified by javascript. The purpose of this post is to make sure that the way I am writing the form is the right way because I am new to nested forms.
Thank you
There are two possibly scenarios you want to consider:
1. A child needs to select an existing parent it belongs to.
2. A child needs to create a brand new parent that it belongs to.
It appears that you want to do #1, select an existing parent. If so, you do not need fields_for. Fields for is for creating new relations.
I'll show you some example code from an application I'm working on about schools, where a student belongs_to a grade level.
app/views/students/_form.html.erb
<%= form_for #student do |student_form| %>
<%= student_form.text_field :first %>
<%= student_form.text_field :last %>
<%= student_form.collection_select :grade_level_id, GradeLevel.all, :id, :name %>
<%= student_form.submit "Save" %>
<% end %>
Now, using your models (Child and Parent):
app/views/children/_form.html.erb
<%= form_for #child do |form| %>
<%= form.text_field :child_name %>
<%= form.number_field :age %>
<%= form.collection_select :parent_id, Parent.all, :id, :name %>
<%= form.submit "Save" %>
<% end %>
Note that I just put Parent.all straight into the collection_select. Creating #all_parents above isn't necessary.
EDIT
If you want to create new parents every time...
app/views/children/_form.html.erb
<%= form_for #child do |form| %>
<%= form.text_field :child_name %>
<%= form.number_field :age %>
<% form.fields_for :parent, #child.parent do |parent_fields| %>
<%= parent_fields.text_field :parent_name %>
<%= form.submit "Save" %>
<% end %>
I'm having issues with the implementation of a nested form for a model with has_many through relationship
I have 3 models: Reservation, Table and Collection (Join Model for these two)
In my Reservation Controller I have these two methods:
def new
#reservation = Reservation.new
#tables = Tables.all
#tables.size.times {#reservation.collections.build}
end
and
def reservation_params
params.require(:reservation).permit(:name, collections_attributes: [ :table_id, :units_sold],
tables_attributes: [:units, :title])
end
my form view is as following:
<%= form_for [current_user, #reservation] do |f| %>
<header>
<h1>Make Reservation</h1>
</header>
<%= f.text_field :name, placeholder: "Name" %>
<%= f.fields_for :collections do |builder| %>
<%= render 'nested_form', :f => builder %>
<% end %>
<%= f.submit "Save" %>
<% end %>
and my _nested_form.html.erb file:
<%= f.number_field :units_sold, placeholder: "Units" %>
<%= check_box_tag :table_id %>
My problem is, whenever I save a new entry on the database he assigns the same table_id to all collections association, e.g:
I want to receive the Parameters hash such as:
"collections_attributes"=>{"0"=>{"units_sold"=>"5", "table_id"=>"1"}, "1"=>{"units_sold"=>"6", "table_id"=>"2"}}}
Instead what I'm getting is:
"collections_attributes"=>{"0"=>{"units_sold"=>"5", "table_id"=>"1"}, "1"=>{"units_sold"=>"6", "table_id"=>"1"}}}
How do I fix this for it to give the correct table_id for each collection?
It would be better if you provide your models' snippet that shows their associations.
Anyway, according to your form; One Reservation has many tables through collections.
change:
<%= check_box_tag :table_id %>
to
<% #tables.each do |table| %>
<li>
<%= f.radio_button :table_id %>
<%= f.label :table_id, table.name %>
</li>
<% end %>
By this, you will be able to choose one table from all for each collection using radio button.
Hope this will help!
I have a model Person with the following attributes:
:name, :state, :age, :town
Let's say I want to be able to edit all of the attributes except for :name from that Person's edit view. Is there a "rails" way to do this, and if so what would I write without looping through each attribute and creating a form?
Right now, I've got something like this:
<%= form_for #person do |person_form| %>
<%= person_form.fields_for :age do |age_form| %>
<%= age_form.text_field :age %>
<% end %>
<% end %>
And I would do that for each attribute.
It would be just a standard form since the object you're wrapping the form around has all of the attributes.
<%= form_for #person do |f| %>
<%= f.text_field :state %>
<%= f.text_field :age %>
<%= f.text_field :town %>
<%= f.submit %>
<% end %>
Of course, you can add labels and whatever else you need to the form.
I've got a form for an order and with this, the user have to choose a category then associated product. As I want it to be dynamic, I wrote this :
_form.html.erb
<%= form_for(#order) do |f| %>
<%= f.collection_select :category_id, #categories_list, :id, :name, :prompt => "Selectionner" %>
<%= render :partial => 'products' %>
<%= f.submit 'Enregistrer', :class=>'button add'%>
<% end %>
_products.html.erb :
<%= form_for(Order.new, :remote => true) do |f| %>
<% if !#products.blank? %>
<%= f.label 'Produit :' %><br />
<%= f.select :product_id, #products.collect{ |s| [s.name,s.id]}, :prompt => "Selectionner" %>
<% else %>
<%= f.label 'Produit :' %><br />
<%= f.select :product_id, '' %>
<% end %>
<% end %>
in the controller :
def update_product_select
#products = Product.where(:category_id=>params[:id]).order(:name) unless params[:id].blank?
render :partial => "products", :layout => false, :locals => { :products => #products }
end
For the dynamic part, it works.
But when I click on the submit button, the product ID is not sent !
Can you tell me how is it possible for me to combine dynamic menu and form submitting please ?
Thanks.
I don't understand why you need two forms. Something is wrong here.
Explain a bit more on the workflow if possible.
I see you should either make use of fields_for if you are trying to edit other associated instances of #order.
For a dynamic menu, have a javascript event binding on the category that updates the products list based on the category. Let me know if you need an example.
I think you are looking for this: http://railscasts.com/episodes/88-dynamic-select-menus-revised
It needs a subscription, but you can also see the previous episode to get an idea if you dont want to subscribe.
I'm a bit stuck on a 'has_one' and 'belongs_to' relationship and getting it to properly display in Formtastic. I have a person model that has one picture (a profile picture). I want the user to be able to select the picture using radio buttons. So far, I have:
<% form.inputs do %>
<%= form.input :picture, :as => :radio, :collection => #pictures %>
<% end %>
However, this fails (because the foreign key is stored on the 'belongs_to' side of associations in Rails. Any suggestions?
Ended up using custom controller code to fix. Use a variety of filters, etc.
Came across this in the "related" sidebar. I think this is a good use case for nested attributes -- from the Formtastic README:
Nested forms are also supported (don’t forget your models need to be setup correctly
with accepts_nested_attributes_for). You can do it in the Rails way:
<%= semantic_form_for #post do |form| %>
<%= form.inputs :title, :body, :created_at %>
<%= form.semantic_fields_for :author do |author| %>
<%= author.inputs :first_name, :last_name, :name => "Author" %>
<% end %>
<%= form.buttons %>
<% end %>
Or the Formtastic way with the :for option:
<%= semantic_form_for #post do |form| %>
<%= form.inputs :title, :body, :created_at %>
<%= form.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
<%= form.buttons %>
<% end %>