如何修复此嵌套构建对象关联?

时间:2016-05-16 07:53:17

标签: ruby-on-rails ruby-on-rails-5

我有一个问题&答案模型 - 类似于SO。

我想要做的是在我的问题#显示页面上,我希望用户能够添加他们的答案,并将其与该问题和用户记录相关联。

这就是我所拥有的:

Questions#Show view

        <div class="ibox-content">
          <%= render partial: "answers/form", locals: {answer: @question.answers.build(user: current_user)} %>
        </div>

在我的Answers#_Form

<%= simple_form_for(answer) do |f| %>
  <div class="form-inputs">
    <%= f.input :body %>
  </div>

  <div id="new-post-submission-button">
    <%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
  </div>
<% end %>

这是我的question#show控制器:

def show
end

这是我的answer#create控制器:

  def create
    @answer = Answer.new(answer_params)

    respond_to do |format|
      if @answer.save
        format.html { redirect_to :back, notice: 'Answer was successfully created.' }
        format.json { render :show, status: :created, location: @answer }
      else
        format.html { render :new }
        format.json { render json: @answer.errors, status: :unprocessable_entity }
      end
    end
  end

这是answer_params

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def answer_params
      params.require(:answer).permit(:body, :user_id, :question_id)
    end

然而,一旦我在答案表单中提交了某些内容,它就会创建一个全新的记录(而不是render partial调用构建的记录。

以下是我从pry获得的实际呈现_form.html.erb部分的初始记录:

[1] pry(#<#<Class:0x007fe931ec9768>>)> answer
=> #<Answer:0x007fe9385ec3a0 id: nil, body: nil, user_id: 1538, question_id: 4, created_at: nil, updated_at: nil>

然而,这是在db中提交和创建的内容:

[117] pry(main)> Answer.last
  Answer Load (2.5ms)  SELECT  "answers".* FROM "answers" ORDER BY "answers"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<Answer:0x007f87073772c0
 id: 48,
 body: "Does this one with user_id: 1538 and question_id: 4 get submitted?",
 user_id: nil,
 question_id: nil,
 created_at: Mon, 16 May 2016 07:49:58 UTC +00:00,
 updated_at: Mon, 16 May 2016 07:49:58 UTC +00:00>

请注意user_idquestion_id两者都不同(因为提交完成后,它会创建一个全新的记录,而不是使用通过locals传递给它的记录)。

以最Railsy方式处理我想要做的事情的最佳方式是什么?

修改1

以下是Answer#Create行动中检查的参数:

[1] pry(#<AnswersController>)> answer_params
=> <ActionController::Parameters {"body"=>"Does this one with user_id: 1538 and question_id: 4 get submitted?"} permitted: true>
[2] pry(#<AnswersController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"NYMYT9K2AhLQ7seiYLr01ir/udTDbjmaBEsnEXLTSl/kcZg08f6L+mJW9G/kHMQaODmQhxisfn6Xm3OGMdGcfQ==", "answer"=><ActionController::Parameters {"body"=>"Does this one with user_id: 1538 and question_id: 4 get submitted?"} permitted: false>, "commit"=>"Create Answer", "controller"=>"answers", "action"=>"create"} permitted: false>
[3] pry(#<AnswersController>)> @answer
=> nil
[4] pry(#<AnswersController>)> params[:answer]
=> <ActionController::Parameters {"body"=>"Does this one with user_id: 1538 and question_id: 4 get submitted?"} permitted: false>
[5] pry(#<AnswersController>)> answer_params
=> <ActionController::Parameters {"body"=>"Does this one with user_id: 1538 and question_id: 4 get submitted?"} permitted: true>

修改2

Question#New

  def new
    @question = Question.new
  end

Answer#New

  def new
    @answer = Answer.new
  end

1 个答案:

答案 0 :(得分:0)

我最终想通了。

在我的表格中,我添加了这些隐藏的字段:

  <%= f.input :question_id, as: :hidden %>
  <%= f.input :user_id, as: :hidden %>

然后在我的Answers#Create行动中,我只是这样做了:

question = Question.find(answer_params[:question_id])
user = User.find(answer_params[:user_id])
@answer = question.answers.create(user: user, question: question, body: answer_params[:body])

因为我最终发现,一旦我通过隐藏字段传递它们,就会被允许这样:

[5] pry(#<AnswersController>)> answer_params
=> <ActionController::Parameters {"body"=>"This is a test submission.", "user_id"=>"1535", "question_id"=>"4"} permitted: true>

现在一切都像魅力一样!