I am trying to re-create a stack overflow like app. One user asks a question, and others can answer. I have a nested form indented on the question's page to get answers from other users.
I am having a difficult time to retrieve the data after the answer is posted, and I have set @answer incorrectly on the questions controller page in the update action, and I can't figure out how to properly retrieve this variable given that the params coming through the questions_controller does not have details of the answer set separately. How do I retrieve the params part related to @answer so that I can set the variable, or maybe I need to use different routes for that?
 My form looks like this:
 <%= form_for @question do |form| %>
   <%=form.fields_for :answer do |answer_form| %>
     <div class="form-group">
        <%=answer_form.text_area :answer_attributes, placeholder: "Add your answer", rows:10, class:"form-control" %>
<%=answer_form.hidden_field :user_id, value: current_user.id, class:'d-none' %>
         <%=answer_form.hidden_field :question_id, value: @question.id %>
      </div>
    <% end %>
    <div>
       <%=form.submit 'Post Your Answer', class: 'btn-primary' %>
   </div>
 <% end %>
My Question model looks like this:
 class Question < ApplicationRecord
  has_many :answers, dependent: :destroy
  belongs_to :user
  accepts_nested_attributes_for :answers
  validates :headline, presence: true , length: { minimum: 20 }
  validates :body, presence: true, length: { minimum: 50 }
  validates_associated :answers
end
and the Answer model is:
class Answer < ApplicationRecord
  belongs_to :user
  belongs_to :question
  validates :body, presence: true, length: { minimum: 50 }
end
Questions controller:
class QuestionsController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show]
  before_action :set_question, except: [:index, :new, :create]
  def index
    @questions = Question.all.order("id DESC")
  end
  def show
    @question = Question.find(params[:id])
    @user = User.find(@question.user_id)
    @answers = @question.answers
    @answer = Answer.new
  end
  def new
    @question = Question.new
    @question.answers.new
  end
  def create
    @question = current_user.questions.new(question_params)
    if @question.save
      flash[:notice] = "You have successfully posted your question"
      redirect_to  @question
    else
      @errors = @question.errors.full_messages
      render action: :new
    end
  end
  def edit
    set_question
    @question = Question.find(params[:id]) 
  end
  def update
     @question = Question.find(params[:id])
     @question.update(question_params)
     @answer = @question.answers.new(question_params)
     @question.answers.first.user_id = current_user.id
   if @question.save
     flash[:notice] = "You have sucessfully posted your answer"
     redirect_to @question
   else
      redirect_to new_question_answer_path(@answer), flash: { danger: @question.errors.full_messages.join(",")}
    end
  end
  private
  def set_question
    @question = Question.find(params[:id])
  end
  def question_params
    params.require(:question).permit(:headline, :body, :user_id, :answer, answers_attributes:[:body, :user_id, :question_id])
  end
end
Answers controller:
class AnswersController < ApplicationController
  before_action :find_question
  def index
    @answers = @question.answers
    @user = User.find(@question.user_id)
  end
  def show
    @answer = Answer.find(params[:id])
    @user = User.find(@question.user_id)
  end
  def new
    @answer = Answer.new(:question_id => @question.id)
  end
  def create
    @answer = Answer.new(answer_params)
    if @answer.save
      flash[:notice] = "You have sucessfully created the answer."
      redirect_to(answers_path(@answer, :question_id => @question.id))
    else
      flash[:alert] = "Failed to save the answer."
      @errors = @answer.errors.full_messages
      render :new
    end
  end
  def edit
    @answer = Answer.find(params[:id])
  end
  def update
    @answer = Answer.find(params[:id])
    if @answer.update_attributes(answer_params)
      flash[:notice] = "You have sucessfully updated the answer."
      redirect_to(answer_path(@answer, :question_id => @question.id))
    else
      render :edit
    end
  end
  def delete
    @answer = Asnwer.find(params[:id])
  end
  def destroy
    @answer = Answer.find(params[:id])
    @answer.destroy
    flash[:notice] = "Answer was destroyed"
    redirect_to(answers_path)
  end
  private
   def answer_params
     params.require(:answer).permit(:body, :user_id, :question_id)
   end
   def find_question
     @question = Question.find(params[:question_id])
   end
end
My routes file looks like this:
    Rails.application.routes.draw do
  get 'questions/index'
  root to: 'questions#index'
  resources :questions  do
    resources :answers
  end
  devise_for :users
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
UPDATE: here are the logs from the moment the server was started and the index page displayed to the moment where I go to the questions page and log the answer
   rails server
=> Booting Puma
=> Rails 5.2.2 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.6.0-p0), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Started GET "/questions/11/answers" for 127.0.0.1 at 2019-03-07 16:10:13 +0600
   (1.4ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  ↳ /Users/irina/.rvm/gems/ruby-2.6.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Processing by AnswersController#index as HTML
  Parameters: {"question_id"=>"11"}
  Question Load (0.8ms)  SELECT  "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
  ↳ app/controllers/answers_controller.rb:65
  User Load (2.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/answers_controller.rb:6
  Rendering answers/index.html.erb within layouts/application
  Answer Load (0.9ms)  SELECT "answers".* FROM "answers" WHERE "answers"."question_id" = $1  [["question_id", 11]]
  ↳ app/views/answers/index.html.erb:11
  User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/views/answers/_new.html.erb:7
  Rendered answers/_new.html.erb (61.7ms)
  Rendered answers/index.html.erb within layouts/application (92.7ms)
[Webpacker] Compiling…
Started GET "/questions/11/answers" for 127.0.0.1 at 2019-03-07 16:10:18 +0600
Processing by AnswersController#index as HTML
  Parameters: {"question_id"=>"11"}
  Question Load (1.4ms)  SELECT  "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
  ↳ app/controllers/answers_controller.rb:65
  User Load (1.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/answers_controller.rb:6
  Rendering answers/index.html.erb within layouts/application
  Answer Load (1.3ms)  SELECT "answers".* FROM "answers" WHERE "answers"."question_id" = $1  [["question_id", 11]]
  ↳ app/views/answers/index.html.erb:11
  User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/views/answers/_new.html.erb:7
  Rendered answers/_new.html.erb (9.3ms)
  Rendered answers/index.html.erb within layouts/application (18.5ms)
Completed 200 OK in 133ms (Views: 108.3ms | ActiveRecord: 18.4ms)
[Webpacker] Compilation failed:
Hash: 53a953077891e4cef2e8
Version: webpack 3.12.0
Time: 2928ms
                                  Asset       Size  Chunks             Chunk Names
    application-c57a289721a93641de38.js     3.1 kB       0  [emitted]  application
application-c57a289721a93641de38.js.map    2.49 kB       0  [emitted]  application
                          manifest.json  142 bytes          [emitted]
   [0] ./app/javascript/packs/application.js 346 bytes {0} [built] [failed] [1 error]
ERROR in ./app/javascript/packs/application.js
Module build failed: SyntaxError: Unexpected token (14:15)
  12 |     if(window.railsEnv && window.railsEnv === 'development'){
  13 |       try {
> 14 |         render(<App />, reactElement)
     |                ^
  15 |       } catch (e) {
  16 |         render(<RedBox error={e} />, reactElement)
  17 |       }
Completed 200 OK in 11715ms (Views: 11626.9ms | ActiveRecord: 27.7ms)
Started PATCH "/questions/11" for 127.0.0.1 at 2019-03-07 16:10:41 +0600
Processing by QuestionsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"q7HQt4uGPwBIIz0icswfJLWMRk6MiopIfWu9JBcjkuX1VpGBdwlwZu903NDuebSaX8Y90VHnvcEoaV8unV2zkw==", "question"=>{"answer"=>{"answer_attributes"=>"This is the test answer to see how the information goes through", "user_id"=>"3", "question_id"=>"11"}}, "commit"=>"Post Your Answer", "id"=>"11"}
  User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ /Users/irina/.rvm/gems/ruby-2.6.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
  Question Load (0.5ms)  SELECT  "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
  ↳ app/controllers/questions_controller.rb:55
  CACHE Question Load (0.0ms)  SELECT  "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
  ↳ app/controllers/questions_controller.rb:39
Unpermitted parameter: :answer
   (0.5ms)  BEGIN
  ↳ app/controllers/questions_controller.rb:40
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/questions_controller.rb:40
  Answer Load (0.5ms)  SELECT "answers".* FROM "answers" WHERE "answers"."question_id" = $1  [["question_id", 11]]
  ↳ app/controllers/questions_controller.rb:40
   (0.3ms)  COMMIT
  ↳ app/controllers/questions_controller.rb:40
Unpermitted parameter: :answer
   (0.3ms)  BEGIN
  ↳ app/controllers/questions_controller.rb:44
  CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/questions_controller.rb:44
   (0.4ms)  ROLLBACK
  ↳ app/controllers/questions_controller.rb:44
Completed 500 Internal Server Error in 97ms (ActiveRecord: 8.3ms)
ActionController::UrlGenerationError (No route matches {:action=>"new", :controller=>"answers", :question_id=>nil}, missing required keys: [:question_id]):
app/controllers/questions_controller.rb:48:in `update'
UPDATE NO 2. It looks like because of this falsely set @answer the @question does not get saved as intended and the second part of the conditional kicks redirecting to the new_question_answer_path. I tried to update it to edit_question_answer_path and it gives the same error that no route matches.
If I open the answer in Pry I get the following object:
[1] pry(#<QuestionsController>)> @answer
=> #<Answer:0x00007fc3ec823c98
 id: nil,
 body: nil,
 question_id: 11,
 user_id: 3,
 selected: nil,
 created_at: nil,
 updated_at: nil>
UPDATE No 3 Looks like changing my routes.rb to
 Rails.application.routes.draw do
  resources :questions, :has_many => :answers
  root to: 'questions#index'
  resources :questions  do
      resources :answers
    end
  devise_for :users
end
and also changing the form for the answer to this
<h2> Your Answer </h2>
<%= form_for [@question, Answer.new] do |form| %>
     <div class="form-group">
        <%=form.text_area :body, placeholder: "Add your answer", rows:10, class:"form-control" %><br>
         <%=form.hidden_field :user_id, value: current_user.id, class:'d-none' %>
         <%=form.hidden_field :question_id, value: @question.id %>
      </div>
    <div>
       <%=form.submit 'Post Your Answer', class: 'btn-primary' %>
   </div>
<% end %>
did the trick and helped to fix the problem. I am not sure if this is a perfect fix though)
