0

I'm quite new to Ruby and Ruby on Rails. Right now in my app, I have a microposts, questions, and answers controllers. For the routes, I have questions nested under microposts, and answers nested under question. Inside microposts I have a question partial and a question forms partial, and inside the question partial I have an answer partial and an answer forms partial. Particularly, the error is triggered on the answer forms partial.

My routes:

  resources :microposts,          only: [:show, :create, :destroy] do
    resources :questions
  end
  resources :questions do
    resources :answers
  end

(micropost) show.html.erb

<% provide(:title, @micropost.title) %>
<div class="center jumbotron">
  <h2><%= link_to @micropost.user.name, @micropost.user %></h2>
  <h1><%= @micropost.title %></h1>
  <p><%= @micropost.content %>
    <%= image_tag @micropost.picture.url if @micropost.picture? %>
  </p>
  <p>
    Posted <%= time_ago_in_words(@micropost.created_at) %> ago.
    <% if current_user?(@micropost.user) %>
      <%= link_to "delete", @micropost, method: :delete,
                  data: { confirm: "Are you sure you want to delete this post?" } %>
    <% end %>
  </p>
  <div class="row">
    <% if @micropost.questions.any? %>
        <ol class="questions">
          <%= render @micropost.questions %>
        </ol>
    <% end %>
    <% if current_user?(@micropost.user) %>
        <%= render 'questions/question_form' %>
    <% end %>
  </div>
</div>

_question.html.erb

<li id="question-<%= @micropost.questions %>">
  <span class="content"><%= question.qcontent %></span>
  <% if question.answers.any? %>
      <ol class="answers">
        <%= render question.answers %>
      </ol>
  <% end %>
  <% if logged_in? %>
      <%= render 'answers/answer_form' %>
  <% end %>
</li>

_answer_form.html.erb

<div class="col-md-6 col-md-offset-3">
  <%= form_for([@question, new_question_answer_path]) do |f| %>
      <%= render 'shared/error_messages', object: f.object %>
      <div class="field">
        <%= f.text_area :acontent, placeholder: "Enter your answer"  %></div>
      <%= f.submit "Submit Answer", class: "btn btn-primary" %>
  <% end %>
</div>

answers_controller.rb

class AnswersController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]

  def new
    @question = Question.find(params[:question_id])
    @answer = Answer.new
  end

  def create
    @question = Question.find(params[:question_id])
    @answer = @question.answers.build(answer_params)
    redirect_to micropost_path(@micropost)
    if @question.save
      flash[:success] = "Answer submitted!"
    end
  end

  def destroy
    @question.destroy
    flash[:success] = "Answer deleted"
  end

  private

  def answer_params
    params.require(:answer).permit(:acontent)
  end

end

This is the error I get when I load my microposts page when there is a question posted:

ActionView::Template::Error (No route matches {:action=>"new", :controller=>"answers", :id=>"4"} missing required keys: [:question_id]):

So I figure that all I need to do is pass it question_id. But, how do I do that?

Brian T.
  • 1
  • 2

3 Answers3

0

For your routes, you want to nested like

resources :microposts,          only: [:show, :create, :destroy] do
  resources :questions do
    resources :answers
  end
end

This would get your url like

/microposts/:micropost_id/questions/:question_id/answers/answer_id

Judging by your description, this is what you are looking for. This may solve your issue. Or let me know if I misinterpreted your question.

This, however, is not good practice, you never want to nest more than one level deep.

davidhu
  • 9,523
  • 6
  • 32
  • 53
  • Yes, I also read that it is not good to nest more than one level deep. I need to find a way to pass question_id to new_question_answer_path. I tried new_question_answer_path(@question) but it gives me the same error. – Brian T. Aug 26 '16 at 03:16
0

Try:

# answers_controller.rb
def new
  @question = Question.find(params[:question_id])
  @answer = Answer.new(question: @question)
end

# _answer_form.html.erb
<%= form_for([@question, @answer]) do |f| %>

Also you can take a look at https://stackoverflow.com/a/4537247

Community
  • 1
  • 1
Eric
  • 68
  • 6
0

Because you use new_question_answer_path - url helper for nested resource, you need to provide question_id for it: new_question_answer_path(@question). Also I don't see the reason why do you need answers not only as a nested into questions resourse so @davidhu2000 provided is more correct routing code.

egoholic
  • 317
  • 1
  • 6