Save Question(s) form with one submit button - ruby-on-rails

In my rails app I have a questions view that renders all the questions in a poll. I want to make sure that all the questions rendered can be submitted using 1 submit button.
If that's not possible, how can I render one question after another until there are no more quesitons?
The front-end code goes:
poll_question.html.erb:
<% #poll.questions.each do |qst| %>
<%= render "questions" , qst: qst%>
<p style="color: red"><%= notice %></p>
<hr>
<% end %>
Render partial _questions.html.erb:
<%= form_with model: qst.question_results.build, url: question_question_results_path(qst) do |f| %>
<% qst_type = qst.poll.voting_type %>
<% option_length = qst.options.count %>
<%= f.hidden_field :question_id, value: qst.id %>
<%= f.hidden_field :option_id, value: qst.options.first.id %>
<h3> <%= qst.title %></h3>
<h6> <%= qst.description %> </h6>
<ul>
<% qst.options.each do |option| %>
<%= f.fields_for :question_result_ranks, f.object.question_result_ranks.build do |rank_f| %>
<%= rank_f.hidden_field :option_id, value: option.id %>
<%= option.title %>
<%= rank_f.select :rank, options_for_select((1..option_length).step(1)) %><br>
<% end %>
<% end %>
</ul>
<div>
<%= f.submit "Save Answer" %>
</div>
<% end %>
Here is my routes.rb
resources :users do
resources :polls
# Questions
resources :questions, shallow: true do
resources :options
resources :question_results
patch "/create_question_results", to: "questions#create_question_results", as: "create_question_results"
end
end
Edit: These views are not rendered under the Poll and Question Controller, They are rendered under the session module which has no relationships in the model.

If you want to submit all the questions with one click, you should use a nested form.
Main template poll_question.html.erb:
<%= form_with model: #poll do |form| %>
<%= form.fields_for :questions do |f| %>
# This block renders a collection of partials.
<%= render 'question', f: %>
<% end %>
<%= form.submit 'Save' %>
<% end %>
Question form _quiestion.html.erb:
<% qst = f.object %>
<% qst_type = qst.poll.voting_type %>
<% option_length = qst.options.count %>
<%= f.hidden_field :question_id, value: qst.id %>
<%= f.hidden_field :option_id, value: qst.options.first.id %>
<h3> <%= qst.title %></h3>
<h6> <%= qst.description %> </h6>
<ul>
<% qst.options.each do |option| %>
<%= f.fields_for :question_result_ranks, f.object.question_result_ranks.build do |rank_f| %>
<%= rank_f.hidden_field :option_id, value: option.id %>
<%= option.title %>
<%= rank_f.select :rank, options_for_select((1..option_length).step(1)) %><br>
<% end %>
<% end %>
</ul>
And don't forget to add accepts_nested_attributes_for :questions in your poll model.

Related

fields_for not nesting attributes

I have this form:
<%= form_for(:quiz_responses, url: quiz_responses_path) do |f| %>
<%= f.hidden_field :name, value: #survey.name %>
<%= fields_for :questions do |ff| %>
<% #questions.each do |question| %>
<ul>
<%= ff.hidden_field "#{question_counter}", value: question.content %>
<%= ff.label question.content %>
<%= fields_for :answers do |fff| %>
<% question.answers.each do |answer| %>
<%= fff.hidden_field "#{answer_counter}", value: answer.content %>
<% answer_counter += 1 %>
<%= fff.label answer.content %>
<%= f.radio_button("user_answer[#{user_answer_counter}]", answer.content) %>
<% end #questions.answers.each do %>
<% end #fields_for answers %>
<% user_answer_counter += 1 %>
</ul>
<% question_counter += 1 %>
<% end ##questions.each do %>
<% end #fields_for questions %>
<%= f.submit %>
<% end #form_for%>
My wanted result is that I get a params hash with :quiz_responses containing a :questions hash, and each question value inside that hash contains an :answers hash containing answers. But this is what I see:
where there's a questions hash containing all the questions and a separate answers hash containing all the answers, and somehow user_answeris inside quiz_responses. How do I fix this mess?
You need to call fields_for on your form object like this:
<%= form_for(:quiz_responses, url: quiz_responses_path) do |f| %>
# ...
<%= f.fields_for :questions do |ff| %>
# ...
<%= ff.fields_for :answers do |fff| %>
# ...

Quiz form submission format

I created three models, "Survey", "Question", and "Answer". Survey has_many Questions which has_many Answers (and they all belong to the model above them).
I create a quiz using this form in the SurveyController edit action. In the show action of the SurveyController, I want to take the quiz I created and generate the quiz itself for the user to take. It submits to the create action of QuizResponses controller.
<%= form_for(:quiz_responses, url: quiz_responses_path) do |f| %>
<%= hidden_field_tag :name, #survey.name %>
<% #questions.each do |question| %>
<ul>
<%= hidden_field_tag :question, question.content %>
<%= f.label question.content %>
<% question.answers.each do |answer| %>
<%= f.label answer.content %>
<%= f.radio_button(:user_answer, answer.content) %>
<% end %>
</ul>
<% end ##questions.each do %>
<%= f.submit %>
<% end #form_for%>
But it shows up in a really ugly format. How do I change the form to make it look better (IE answer text with the checkbox?
The question is too broad, but here's a simple solution:
<%= form_for(:quiz_responses, url: quiz_responses_path) do |f| %>
<%= hidden_field_tag :name, #survey.name %>
<% #questions.each do |question| %>
<%= hidden_field_tag :question, question.content %>
<!-- question title -->
<h3><%= f.label question.content %></h3>
<!-- questions answers -->
<ul>
<% question.answers.each do |answer| %>
<!-- use display:inline-block or float to make inline li -->
<li>
<%= f.label answer.content %>
<%= f.radio_button(:user_answer, answer.content) %>
</li>
<% end %>
</ul>
<% end %>
<!-- submit -->
<p>
<%= f.submit %>
</p>
<% end %>

Nested routes form_for partial not working for new and edit actions - Rails 4

I used the generator to scaffold categories and questions.
my routes.rb
resources :categories do
resources :questions do
resources :choices, only: [:index]
end
end
my problem occurs when i try to add or edit a question.
here is my partial form, before you ask the relationship works ok.
<%= form_for [#question.category, #question] do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :question_type %><br>
<%= f.text_field :question_type %>
</div>
<div class="field">
<%= f.label :explanation %><br>
<%= f.text_field :explanation %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :category_id %><br>
<%= f.text_field :category_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
what must i change for it to work? for now i get,
undefined method `questions_path'
Try this
UPDATE
Controller
#category = Category.find(params[:category_id])
#question = #category.questions.new
_form
<%= form_for([#category, #question]) do |f| %>
Reference
You should pass parent and then build child for same for new object.
<%= form_for [#category, #category.questions.build] do |f| %>
To edit:
<%= form_for [#category, #category.questions.first_or_your_object] do |f| %>
Like this :
<% if #category.new_record? %>
<%= form_for [#category, #category.questions.build] do |f| %>
<% else %>
<%= form_for [#category, #category.questions.first_or_your_object] do |f|
<% else %>
Also add in your category model:
accepts_nested_attributes_for :questions
Add this line to your category.rb model file:
accepts_nested_attributes_for :questions
Also, in your controller:
#category = Category.find(params[:category_id])
#question = Question.new(category: #category)
and form:
<%= form_for([#category, #question]) do |f| %>

Using form_for with Awesome Nested Set

I have a Comment model with the acts_as_nested_set enabled, but when I try to do something like this (for nested comments), i receive the error "comment_comments_path not found", presumably because the default pathing doesn't work with Awesome Nested Set. How do I get around this?
<%= form_for([#comment, #comment.children.build]) do |f| %>
<%= f.text_area :content, :placeholder=>'What do you think?'%>
<%= f.submit 'Submit Reply'%>
<% end %>
I also tried this:
<%= form_for(#comment) do |f| %>
<% #comment.children.each do |sub| %>
<%= f.fields_for :children, sub do |child| %>
<%= child.text_area :content, :placeholder=>'What do you think?'%>
<%= f.submit 'Submit Reply'%>
<% end %>
<% end %>
<% end %>
but it didn't generate a textbox for me to type in.
You're very close, yeah you have to build it first then have fields for, so this:
<% #comment.children.build %>
<%= form_for([#comment]) do |f| %>
<%= f.fields_for :children do |child| %>
<%= child.text_area :content, :placeholder=>'What do you think?'%>
<% end %>
<%= f.submit 'Submit Reply'%>
<% end %>
<% end %>
This will have a form for all existing children + the new one. If you want only a form for a new child then you'll want this instead:
<%= form_for([#comment]) do |f| %>
<%= f.fields_for #comment.children.build, :children do |child| %>
<%= child.text_area :content, :placeholder=>'What do you think?'%>
<% end %>
<%= f.submit 'Submit Reply'%>
<% end %>
<% end %>

Ajax and voting

I have a parent class Car and the /cars/show page lists all of the reviews associated with it. The reviews can be voted on. I am having some difficulty getting the :votes_count to update by JavaScript.
/votes/create.js.erb
$("#votes").html("<%= review.votes_count %>") // this does not work
/cars/show
<% #car.reviews.each do |review| %>
<p id='votes'><%= pluralize(review.votes_count, 'vote') %></p>
<% if current_user %>
<%= form_for(#vote, :remote => true) do |f| %>
<%= f.hidden_field "review_id", :value => review.id %>
<%= f.hidden_field "user_id", :value => current_user.id %>
<%= f.submit "vote" %>
<% end %>
<% end %>
<br />
<%= review.content %>
<% end %>
create.js.erb
<% #car.reviews.each do |review| %>
$("#review_<%= review.id %>").html("<%= pluralize(review.votes_count, 'vote') %>");
<% end %>

Resources