I have records in which I wanted to be displayed with this url: http://localhost:3000/surveys/1/respondents/1
which I have achieved by:
resources :surveys do
resources :respondents
end
And to show the form I do it using: <%= form_for([@survey, @respondent]) do |form| %>
and everything indicates to be fine, my problem comes when it comes to being able to iterate the respondents that belong to the id of the current survey
<% @respondents.each do |respondent| %>
<tr>
<td><%= respondent.name %></td>
<td><%= link_to 'Show', [ @survey, respondent ] %></td>
<td><%= link_to 'Edit', edit_respondent_path(respondent) %></td>
<td><%= link_to 'Destroy', respondent, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Well, in the case of the link to the show view: <%= link_to 'Show', respondent %>
the variable respondent
didn't work, so I modified it this way: <%= link_to 'Show', [ @survey, respondent ] %>
but I can't make it work either, I suppose it has to do with the way I have the loop structured, I appreciate if you can help me
responders_controller.rb
class RespondentsController < ApplicationController
before_action :set_respondent, only: [:show, :edit, :update, :destroy]
# GET /respondents
# GET /respondents.json
def index
@respondents = Respondent.all
end
# GET /respondents/1
# GET /respondents/1.json
def show
respond_to do |format|
format.html
format.pdf { render template: 'respondents/report', pdf: 'Report' }
end
end
# GET /respondents/new
def new
@survey = Survey.find(params[:survey])
@respondent = Respondent.new
@respondent.answers.build
@answer_option = @respondent.answer_options.build
@answer_option.sub_answer_options.build
end
# GET /respondents/1/edit
def edit
@respondent.answers.build
end
# POST /respondents
# POST /respondents.json
def create
@respondent = Respondent.new(respondent_params)
respond_to do |format|
if @respondent.save
format.html { redirect_to survey_respondent_path(@survey, @respondent), notice: 'Respondent was successfully created.' }
format.json { render :show, status: :created, location: @respondent }
ResultMailer.respondent(@respondent).deliver_later
else
format.html { render :new }
format.json { render json: @respondent.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /respondents/1
# PATCH/PUT /respondents/1.json
def update
respond_to do |format|
if @respondent.update(respondent_params)
format.html { redirect_to @respondent, notice: 'Respondent was successfully updated.' }
format.json { render :show, status: :ok, location: @respondent }
else
format.html { render :edit }
format.json { render json: @respondent.errors, status: :unprocessable_entity }
end
end
end
# DELETE /respondents/1
# DELETE /respondents/1.json
def destroy
@respondent.destroy
respond_to do |format|
format.html { redirect_to respondents_url, notice: 'Respondent was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_respondent
@respondent = Respondent.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def respondent_params
params.require(:respondent).permit(:name, :email, :phone, :survey_id, answers_attributes: [:id, :response, :question_id, :respondent_id], answer_options_attributes: [:id, :response, :question_id, :respondent_id, sub_answer_options_attributes: [:id, :answer_option_id, response: [] ]])
end
end
index.html.erb
<p id="notice"><%= notice %></p>
<h1>Respondents</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Survey</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @respondents.each do |respondent| %>
<tr>
<td><%= respondent.name %></td>
<td><%= respondent.email %></td>
<td><%= respondent.phone %></td>
<td><%= respondent.survey.id %></td>
<td><%= link_to 'Show', [ @survey, respondent ] %></td>
<td><%= link_to 'Edit', edit_respondent_path(respondent) %></td>
<td><%= link_to 'Destroy', respondent, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Respondent', new_respondent_path %>
In
link_to
you must specify theid
fromSurvey
to which the belongs toRespondent
, however in your view you pass the object@survey
that is not defined in the actionindex
and therefore has nosurvey
relation.To make the code work, simply change it
@survey
torespondent.survey
:For it to work you must confirm that your relationship
belongs_to
between the modelsRespondent
andSurvey
is correct, ie: