Rails permit nested attributes - ruby-on-rails

I have this nested form, submitted_quiz and submitted_answers. I'll add the basic layout of this form so you can understand it better:
<%= form_for([#user, #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.hidden_field :question_id, :value => question.id %>
<% end %>
<%= f.submit "Submit" %>
<% end %>
So as you can see, I need to permit :quiz_id, :name of submitted_quiz but I also need to permit the nested :question_id of submitted_answers. I know how to permit just one layer (submitted_quiz) but I'm confused on how to permit nested layers.

you can do it in two ways:
1.just permit all params
params.require(:submitted_quiz).permit!
2.or by names:
params.require(:submitted_quiz).permit(:quiz_id, :name, submitted_answers_attributes: [:question_id])

Related

no implicit conversion of Symbol into Integer in view forms

I am working on configuring the apartment gem for my rails app to give users the functionality to create subdomains. I have a nested form and when attempting to access "accounts/new" I am getting the following error:
no implicit conversion of Symbol into Integer in view forms
accounts/new.html.erb
<div>
</div>
<h2>Create an Account</h2>
<%= form_for #account do |f| %>
<%= f.fields_for :owner do |o| %>
<%= form_for o, :email do %>
<%= o.text_field :email, class: 'form-control' %>
<% end %>
<%= form_for o, :password do %>
<%= o.password_field :password, class: 'form-control' %>
<% end %>
<%= form_for o, :password_confirmation do %>
<%= o.password_field :password_confirmation, class: 'form-control' %>
<% end %>
<% end %>
<%= form_for f, :subdomain do %>
<div class="input-group">
<%= f.text_field :subdomain, class: 'form-control' %>
<span class="input-group-addon">.scrumteam.com</span>
</div>
<% end %>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
</div>
</div>
accounts_controller.rb
private
def account_params
params.require(:account).permit(:subdomain, :owner_attributes => [:email, :password, :password_confirmation])
end
You are nesting multiple forms into each other which is not supported in HTML:
See this question for more details: Can you nest html forms?
These form_for lines look invalid in particular:
<%= form_for o, :field_name do %>
Here, o is a special FormBuilder object which should not be fed to form_for. Try this instead:
<%= f.fields_for :owner do |o| %>
<%= o.fields_for :email do %>
Unlike form_for, it is possible to nest fields_for blocks.
Not sure if this is your route problem, but form_for creates an actual form tag in html. You only need (and should have) 1, the fields_for allows you to switch the form helpers to a different object, but you don't need to call form_for again within it. If you're just trying to group your form fields, you can just add some divs and/or labels.

Saving checkbox value in erb - rails

I have a nested form that saves information to three different models. One section of the form uses checkboxes and is supposed to save values 1-5. However, even when the boxes are checked the form returns value 0. I have tried several different variations of code for setting the checked value. Any help would be much appreciated. A section of the form code is below:
<%= form_for #newinstructor do |f|%>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.fields_for :through_ats do |tag_field| %>
<%= label_tag("What categories does your activity fit into?") %><br>
<%= label_tag(:tag, "Cooking") %>
<%= tag_field.check_box(:tag_id, :value => 1) %>
<%= label_tag(:tag, "Art") %>
<%= tag_field.check_box(:tag_id, :value => 2) %>
<%= label_tag(:tag, "Music") %>
<%= tag_field.check_box(:tag_id, :value => 3) %>
<%= label_tag(:tag, "Outdoors") %>
<%= tag_field.check_box(:tag_id, :value => 4) %>
<%= label_tag(:tag, "Food") %>
<%= tag_field.check_box(:tag_id, :value => 5) %>
<% end %>
<%= f.submit %>
<% end %>
Did you permit tag_id in params?
params.require(:instructor).permit(:name,
through_ats_attributes: [:id, :tag_id, :_destroy]
)
To fix the problem I had, I had to uniquely define each of the symbols in tag_field.checkbox, then require/permit them individually in params
so in the form i put:
<%= label_tag("Please check off the categories your activity fits into.") %><br>
<%= label_tag(:tag, "Cooking") %>
<%= tag_field.check_box(:cooking) %>
<%= label_tag(:tag, "Art") %>
<%= tag_field.check_box(:art) %>
instead of :
<%= label_tag("What categories does your activity fit into?") %><br>
<%= label_tag(:tag, "Cooking") %>
<%= tag_field.check_box(:tag_id, :value => 1) %>
<%= label_tag(:tag, "Art") %>
<%= tag_field.check_box(:tag_id, :value => 2) %>
and in the controller:
params.require(:instructor).permit(through_ats: [:cooking, :art, :music, :outdoors, :food])
instead of:
params.require(:instructor).permit(through_ats: [:id, :tag_id])

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 ).

How to submit a form using simple_form_for when what's being submitted isn't part of the model

I'm trying to submit a form that contains fields for both an event and an invitation to that event. Here is my form:
<%= simple_form_for(#event) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title %>
<%= f.input :description %>
<%= f.input :start_at %>
<%= f.input :end_at %>
<%= f.input :all_day %>
<%= f.hidden_field :owner_id, value: current_user.id %>
<% if false %>
<%= f.association :sitter, label_method: lambda { |s| "#{s.name}" }, collection: User.all %>
<%= f.association :group, label_method: lambda { |g| "#{g.group_name}" }, collection: Group.where(:owner_id => current_user.id) %>
<% end %>
<%= f.input :user_emails, as: :text %>
<%= form_tag event_invitations_path, :method => :post do %>_tag :user_emails %>
</div><div>
<%= label_tag "Your message:" %>
</div><div>
<%= text_area_tag :email_message %>
<% end %>
</div>
</br>
<div class="form-actions">
<%= f.button :submit, :class => 'btn-primary' %>
</div>
<% end %>
This is (perhaps obviously) not working. :user_emails is NOT part of the event or invitation model as it's a list of emails that will be used to create invitations. Basically I merged two forms, one that was accepting the email/send invitation piece and one that was accepting the event information. I think I have my controller and model set up properly to take care of this but how do i submit this information as part of the same form without getting an "undefined_method" error (since user_emails doesn't belong to events). Let me know if you want to see my model/controller.
Use FormTagHelper
<%= label_tag "User", "Email"%>
<%= text_area_tag "user_emails", "example#example.com"%>
See the documentation for more options on text_area_tag and label_tag

Select multiple categories in form (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 %>

Resources