Select multiple categories in form (rails) - ruby-on-rails

I've got this tripbuilder which i want to assign categories to. So I've set up the models as where a trip can have any(or more) categories that are in the category table in my database. However; i have no idea how i can set up the form allowing a user to select categories via checkbox. Since fields_for doesn't sound like a solid way to go in this case (Because i want to see all the categories with a checkbox and select as many categories as i want). Can anyone help me out?
I've tried this form:
<%= form_for #trip, :html => {:multipart => true} do |a| %>
<%= a.label :title, "Routetitel" %>
<%= a.text_field :title %>
<%= a.label :description, "Omschrijving" %>
<%= a.text_area :description %>
<%= a.fields_for :categories do |cat| %>
<%= cat.check_box :name %>
<% end %>
<%= a.submit 'Verstuur' %>
<% end %>

At first, you need to setup the relationship between trip and category like this:
class Trip < ActiveRecord::Base
has_and_belongs_to_many :categories
end
Then you can build the form like this:
<%= form_for #trip, :html => {:multipart => true} do |a| %>
<%= a.label :title, "Routetitel" %>
<%= a.text_field :title %>
<%= a.label :description, "Omschrijving" %>
<%= a.text_area :description %>
<% Category.all.each do |cat| %>
<%= check_box_tag "trip[category_ids][]", cat.id, #trip.catergory_ids.include?(cat.id)
<% end %>
<%= a.submit 'Verstuur' %>
<% end %>

Yes, it can be done by using select tag and multiple attribute of select tag.
<% = a.select :categories, Category.all.collect {|c| [c.name, c.id]}, :include_blank => true', :multiple => "multiple" %>

Please Modify your fields_for as described below and check !!!!
<%= a.fields_for "categories[]" do |cat| %>
<%= cat.check_box :name %>
<% end %>

Related

how does fields_for know how many fields to create?

I guess I'm a little confused on how fields_for works. I have an action with this:
3.times { #submitted_quiz.submitted_answers.build }
if I write a form_for like this in the associated view:
<%= form_for(#submitted_quiz) do |f| %>
<%= f.hidden_field :quiz_id, :value => #quiz.id %>
<%= f.hidden_field :name, :value => #quiz.name %>
<%= f.fields_for (:submitted_answers) do |ff| %>
<%= ff.label :content, "Answer" %><br />
<%= ff.text_area :content, :rows => 3 %>
<% end %>
<%= f.submit %>
<% end %>
how does fields_for know to run three times?
Rails will simply check how many submitted_answers your submitted_quiz has and generate appropriate number of fields ( one for each answer obviously ).

Simple Form simple_fields_for only show last record

I have a nested simple form to edit a user. The user has a profile he/she can update, and a new record is written to the profile table.
simple_fields_for shows all profile records of a user due to the relationship user 1 to many profile records. However, I would like to only show the newest profile record in the form! How can I accomplish that?
<%= simple_form_for(#user) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :lang %>
<%= f.input :firstname %>
<%= f.input :lastname %>
<%= f.input :email %>
<%= f.input :born %>
<%= f.input :gender %>
<%= f.simple_fields_for :profile do |p| %> # the magic needed here
<%= p.input :postal_code %>
<%= p.input :core %>
<%= p.input :daytime %>
<%= p.input :style %>
<% end %>
<% if #is_new %>
<%= f.simple_fields_for :status do |s| %>
<%= s.input :entered, as: :hidden, input_html: { value: Time.current } %>
<% end %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Little late, but accepted answer is not 100% accurate. (Would just make this a comment, but no rep.) I would do this like so:
Assuming you have
class User < ActiveRecord::Base
has_many :profiles
...
def latest_profile
profiles.order(...) # query to get whatever record it is you want
end
end
your simple_fields_for can just be
<%= f.simple_fields_for :profiles, f.object.latest_profile do |p| %>
Note the pluralization of :profiles, and that we don't need to clutter the controller with an additional instance variable because you can access the object in the form. (Using the singular will work I believe, but you will not get params with a key in the form of :profiles_attributes, meaning even more code to account for unique params.)
The edit action:
class user > ApplicationController
...
def edit
#profile = #user.profile.order("saved DESC").first
end
...
end
The working form:
<%= simple_form_for(#user) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :lang %>
<%= f.input :firstname %>
<%= f.input :lastname %>
<%= f.input :email %>
<%= f.input :born %>
<%= f.input :gender %>
<%= f.simple_fields_for :profile, #profile do |p| %> # the magic needed here
<%= p.input :postal_code %>
<%= p.input :core %>
<%= p.input :daytime %>
<%= p.input :style %>
<% end %>
<% if #is_new %>
<%= f.simple_fields_for :status do |s| %>
<%= s.input :entered, as: :hidden, input_html: { value: Time.current } %>
<% end %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>

Nested rails form with checkboxes HASBTM

I have form partial that allows the user to enter the subject and message that will be included in the outbound email. I want to allow the users to select the recipients of the email from the contacts that are associated with the invoice that the email belongs to. The email recipients that are selected through the nested form are to be stored in a separate table.
class EmailRecipient < ActiveRecord::Base
attr_accessible :contact_id, :email_id
belongs_to :email
end
class Email < ActiveRecord::Base
attr_accessible :subject, :message, :invoice_id, :email_recipients_attributes
belongs_to :invoice
has_many :email_recipients
accepts_nested_attributes_for :email_recipients
end
<%= simple_form_for [:invoice, #email], html: {class: "form-horizontal"} do |f| %>
<%= f.error_notification %>
<% #invoice.contacts do |c|%>
<%= f.fields_for :email_recipients do |builder| %>
<%= builder.input :contact_id, :as => :check_boxes %>
<%= c.name %><br/>
<% end %>
<% end %>
<%= f.input :subject, :as => "string" %>
<%= f.input :message, :input_html => { :class => 'span7', :rows => 10 } %>
<div class="form-actions">
<%= f.button :submit, "Send Invoice", :class => 'btn-warning' %>
<%= link_to 'Cancel', invoice_path(#invoice), :class => 'btn' %>
</div>
<% end %>
This isn't the prettiest answer, so I would love to see a better solution, but it gets the job done until my skills improve.
In the controller for the parent form I added:
#invoice.contacts.each { |c| #email.email_recipients.build(contact_id: c.id) }
This builds the records for all contacts whether they are needed or not. Then in the form partial I modified the nested form:
<%= simple_form_for [:invoice, #email], html: {class: "form-horizontal"} do |f| %>
<%= f.error_notification %>
<% count = 0 %>
<%= f.simple_fields_for :email_recipients do |email_recipients_form| %>
<%= email_recipients_form.input :_destroy, as: :boolean, :label => false do %>
<%= email_recipients_form.check_box :_destroy, {}, "false", "true" %>
<% contact = #invoice.contacts.find(#email.email_recipients[count].contact_id) %>
<%= contact.name + " (" + contact.email + ")" %>
<% end %>
<%= email_recipients_form.input :contact_id, as: :hidden %>
<% count += 1 %>
<% end %>

Rails 3.1 - Displaying form values on Edit?

I feel like this should be really really simple, but I'm completely stuck!
In a form I might have a field like:
<%= f.text_field :name, :class => "text" %>
On edit, this pulls back in the value submitted on create, that's fine. But I want to prevent certain fields from being edited. I know I can disable the field or hide it, but I'd like to be able to pull in the values to display and use in other ways. How do I access them?
In this case I've tried things like:
<%= f.track.name %>
<%= track.name %>
<%= #track.name %>
But none of the above work!
Any ideas folks?
EDIT: (I'm using nested forms for this)
<%= form_for(#release, :html => { :multipart => true }) do |f| %>
<h3>Upload Tracks for <%= #release.title %></h3>
<%= f.fields_for :tracks do |builder| %>
<%= render 'upload_track_fields', :f => builder %>
<% end %>
<%= f.submit "Upload Tracks", :class => "submit" %>
<% end %>
And the upload_track_fields that are rendered:
<%= f.text_field :position, :class => "text" %>
<%= f.text_field :name, :class => "text" %>
<%= f.text_field :isrc, :class => "text" %>
<%= f.text_field :version, :class => "text" %>
<%= f.file_field :track, :class => "text" %>
<%= f.hidden_field :primary_genre_id %>
<%= f.hidden_field :secondary_genre_id %>
<%= f.hidden_field :alt_primary_genre %>
<%= f.hidden_field :alt_secondary_genre %>
<%= f.hidden_field :asset_tier %>
<%= f.hidden_field :preview_start %>
<%= f.hidden_field :parental_advisory %>
<%= f.hidden_field :available_separately %>
<%= f.hidden_field :_destroy %>
I've hidden most of the fields to prevent editing, but still need to see some of the fields so they're left as text fields. I tried to disable them, but that stops any changes (specifically the file upload) working.
In short, i'd prefer to display most of the above as text rather than form fields.
In the main form:
<% index = 0 %>
<% f.fields_for :tracks do |builder| %>
<%= #release.tracks[index].name %>
<%= render 'upload_track_fields', :f => builder %>
<% index += 1 %>
<% end %>
In the nested form:
<%= f.text_field :position, :class => "text" %>
# Notice that there's no "name" attribute
<%= f.text_field :isrc, :class => "text" %>
<%= f.text_field :version, :class => "text" %>
<%= f.file_field :track, :class => "text" %>
What I did in the first snippet is dirty, but I never used fields_for so I don't know how to get the actual index. I looked in Google, but I didn't find a solution so far.
I can't try it right now, I'll do it when I'll be home.
I suggest using this while finding a way to get the index.
Good luck!
As those who have commented said, I'd assume the <%= #track.name %> should work, if you have #track = #release.track (for instance) in your edit method in the controller.
Instead of keeping track of the index you can access the associated objects through builder, it's actually a track
<% f.fields_for :tracks do |builder| %>
<%= builder.object.name %>
<%= render 'upload_track_fields', :f => builder %>
<% end %>

Formtastic select list

<% semantic_form_for(#product, :html => {:multipart => true}) do |f| %>
<% f.inputs do %>
<%= f.input :name %>
<%= f.input :price %>
<%= f.input :pno %>
<%= f.input :description %>
<%= f.input :shop_category %>
<% end %>
<% end %>
Product belongs to Shop_category, Shop_category belongs to Shop.
How to change the line :
<%= f.input :shop_category %>
To show only shop_categories that belongs to Shop with id for example 15 instead of showing all shop_categories in the select box ?
There's a :collection option for the select input.
<%= form.input :shop_category, :collection => #shop.ShopCategories %>
So you can, by providing a Hash to that collection attribute, display the categories you need, with the required conditions.
Also, if you set the shop_category in the controller, it will already be selected as a default value.

Resources