从嵌套表单中检索数据

时间:2019-03-07 09:51:26

标签: ruby-on-rails forms nested

我正在尝试重新创建类似应用程序的堆栈溢出。一个用户问一个问题,其他人可以回答。我在问题页面上缩进了一个嵌套表单,以从其他用户那里获得答案。

发布答案后,我很难找回数据,并且我在更新操作中的问题控制器页面上未正确设置@answer,并且我不知道如何正确地获取数据假设通过questions_controller传递的参数没有单独设置答案的详细信息,则此变量为空。如何检索与@answer相关的params部分,以便可以设置变量,或者可能需要为此使用不同的路由?  我的表单如下:

 <%= 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 %>

我的问题模型如下:

 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

,答案模型为:

class Answer < ApplicationRecord
  belongs_to :user
  belongs_to :question
  validates :body, presence: true, length: { minimum: 50 }
end

问题控制器:

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

答案控制器:

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

我的路线文件如下:

    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

更新:这是从服务器启动到显示索引页面到我进入问题页面并记录答案的那一刻的日志

   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'

更新NO2。由于此错误设置了@answer,因此@question无法按预期方式保存,并且条件踢的第二部分重定向到new_question_answer_path。我尝试将其更新为edit_question_answer_path,并且给出了相同的错误,没有路由匹配。

如果我在Pry中打开答案,则会得到以下对象:

[1] pry(#<QuestionsController>)> @answer
=> #<Answer:0x00007fc3ec823c98
 id: nil,
 body: nil,
 question_id: 11,
 user_id: 3,
 selected: nil,
 created_at: nil,
 updated_at: nil>

更新3 好像将我的route.rb更改为

 Rails.application.routes.draw do
  resources :questions, :has_many => :answers
  root to: 'questions#index'
  resources :questions  do
      resources :answers
    end
  devise_for :users
end

,并更改答案的形式

<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 %>

解决了问题,并帮助解决了问题。我不确定这是否是完美的解决方法)

1 个答案:

答案 0 :(得分:0)

就像将我的route.rb更改为

  Rails.application.routes.draw do
      resources :questions, :has_many => :answers
      root to: 'questions#index'
      resources :questions  do
          resources :answers
      end
      devise_for :users
   end

并更改答案的形式

 <%= 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 %>

解决了问题,并帮助解决了问题。我不确定这是否是完美的解决方法)