I'm trying to make a report with predefined questions.
I have made questions from the scaffold and filled it.
Now is to assign answer fields per each questions.
[DATA TYPE]
class Report < ActiveRecord::Base
has_many :answer_singles
end
class AnswerSingle < ActiveRecord::Base
belongs_to :report
end
reports/_form.html.erb
<div class="question">
<% QuestionSingle.all.each_with_index do |question, index| %>
<p><%= index+1 %>. <%= question.content %></p>
<p>
<%= f.fields_for :answer_singles do |answer| %>
<%= answer.text_area :content %>
<% end %>
</p>
<% end %>
</div>
it shows well but once submit it makes error
1. Question 1
[text area]
2. Question 2
[text area]
[error when submit]
AnswerSingle(#18194030) expected, got Array(#1133380)
I think the reason is using :answer_singles for fields for.
Is there any better code to implement this?
By making it nested_attributes I'm able to control it but still some
weird loop.
I don't fully understand how loop works in rails so please advise.
First this code makes one text area per each question.
<div class="question">
<% QuestionSingle.all.each_with_index do |question, index| %>
<p><%= index+1 %>. <%= question.content %></p>
<%= f.fields_for :answer_singles, {:question_id => :index} do
answer> %>
<%= answer.text_area :content %>
<% end %>
<% end %>
</div>
After I put answers and edit it makes number of answer text area same as
questions.
Please let me know how I can make the text area per question.
reports_controller.rb
def new
@report = Report.new
@report.answer_singles.build
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @report }
end
end
_form.html.erb
<%= form_for(@report) do |f| %>
<% if @report.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@report.errors.count, "error") %> prohibited
this report from being saved:</h2>
<ul>
<% @report.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
What I meat to do was to assign question_single_id when I fill the
answer :content.
And look up a text_area per each question.
Is there any good solution for text_area and fields_for usage?
I know I'm way far from CRUD development but what to do. (codes are
getting uglier)
What i should implement is like a quiz system with given questions.
User login -> answer the given questions -> end
Admin -> edit questions or review user answers -> end
So, with nested_attributes, you're not supposed to iterate over
anything at all - f.fields_for :answer_singles will iterate over all
the report's AnswerSingle object and yield to the block once for each
one. With this way of thinking if you want one AnswerSingle for each
QuestionSingle then you'd want to do something like this in your
controller
QuestionSingle.each do |qs|
report.answer_singles.build ...
end
passing to build whatever attributes need to be set on the
answer_single to link it to the question single it corresponds to.
I have changed my code according to it.
But in the form how I can implement this?
Once I'm using the same code it will display 3 fields since it's using
fields_for loop for all answers.
I have changed my code according to it.
But in the form how I can implement this?
Once I'm using the same code it will display 3 fields since it's using
fields_for loop for all answers.
just
<%= field_for :answer_singles do |f| %>
...
<% end %>
will iterate over all of report.answer_singles and execute the block
(e.g. to display a heading & a text area). rails takes cate of
generating different names for form elements so that it doesn't get
all mashed together. Since these are all unsaved elements, you'd
probably want a hidden input to track the question id for the question
corresponding to the text area you are showing.
QuestionSingle.each do |qs|
report.answer_singles.build ...
end
so answer_single generated as many as questions.
So when I call answer_singles in the fields for it calls every
answer_singles generated.
<div class="question">
<% QuestionSingle.all.each_with_index do |question, index| %>
<p><%= index+1 %>. <%= question.content %></p>
<%= f.fields_for :answer_singles do |answer| %>
<%= answer.text_area :content %>
<%= answer.hidden_field :question_single_id, {:value => index}
%>
<% end %>
<% end %>
</div>
So it's entirely normal that fields_for :answer_singles iterates over
all of them - that's how nested attributes work. If i were you i would
ditch the iteration over QuestionSingle and leave the iteration stuff
to fields_for - when displaying a given answer single I assume that
you're able to locate the corresponding question to display it's
content.
But having relationship report->question->answer will lead to
unnecessary generation of the question per each report. In my case,
question is same for all reports.
Could you please guide me what I should do then?
I feel like I'm stuck in db model now.