Rails 6:嵌套表单不保存

问题描述

我一直试图在 Rails 6 中运行一个嵌套表单的简单测试示例,但到目前为止我还没有能够创建一个有效的示例。据我所知,我在我的模型中创建了一个正确的关联,添加一个嵌套表单,允许参数接受嵌套属性。 每当我提交表单时,我都会收到 Completed 422 Unprocessable Entity 这就是我碰壁的地方,不知道该怎么做才能继续。

投票模型

class Poll < ApplicationRecord
  has_many :questions
  accepts_nested_attributes_for :questions,allow_destroy: true,reject_if: :all_blank
  validates_presence_of :title
end

问题模型

class Question < ApplicationRecord
  belongs_to :poll
  validates_presence_of :content,:poll_id
end

轮询控制器

class PollsController < ApplicationController
before_action :set_poll,only: %i[ show edit update destroy ]

# GET /polls or /polls.json
  def index
  @polls = Poll.all
end

# GET /polls/1 or /polls/1.json
def show
end

# GET /polls/new
def new
  @poll = Poll.new
  2.times { @poll.questions.build}
end

# GET /polls/1/edit
  def edit
end

# POST /polls or /polls.json
def create
  @poll = Poll.new(poll_params)
  respond_to do |format|
    if @poll.save
     format.html { redirect_to @poll,notice: "Poll was successfully created." }
     format.json { render :show,status: :created,location: @poll }
    else
     # raise poll_params.inspect  
     format.html { render :new,status: :unprocessable_entity }
     format.json { render json: @poll.errors,status: :unprocessable_entity }
   end
 end
end

# PATCH/PUT /polls/1 or /polls/1.json
def update
  respond_to do |format|
    if @poll.update(poll_params)
      format.html { redirect_to @poll,notice: "Poll was successfully updated." }
      format.json { render :show,status: :ok,location: @poll }
    else
      format.html { render :edit,status: :unprocessable_entity }
      format.json { render json: @poll.errors,status: :unprocessable_entity }
    end
  end
end

# DELETE /polls/1 or /polls/1.json
def destroy
 @poll.destroy
 respond_to do |format|
   format.html { redirect_to polls_url,notice: "Poll was successfully destroyed." }
   format.json { head :no_content }
 end
end

private
  # Use callbacks to share common setup or constraints between actions.
 def set_poll
   @poll = Poll.find(params[:id])
 end

 # Only allow a list of trusted parameters through.
 def poll_params
   params.require(:poll).permit(:title,:questions_attributes => [:id,:content,:_destroy] )
 end
end

_form.html.erb

<%= form_for(@poll) do |f| %>
...

<fieldset>
<div>
    <%= f.label :title %>
    <%= f.text_field :title %>
</div>

    <legend>Questions:</legend>
    <%= f.fields_for :questions do |questions_form| %>
        <%= render "question_fields",f: questions_form %>
    <% end %>

    <%= link_to_add_fields "Add Questions",f,:questions %>
    <input name="authenticity_token" 
           type="hidden" 
           value="<%= form_authenticity_token %>"/>
</fieldset>

<%= f.submit %>
<% end %>

_question_fields.html.erb

<div class="nested-fields">
<%= f.hidden_field :_destroy %>
<div>
    <%= f.label :content %>
    <%= f.text_field :content %>
</div>
<div>
    <%= link_to "Remove",'#',class: "remove_fields" %>
</div>
</div>

当我提交表单时,我得到

Started POST "/polls" for ::1 at 2021-04-06 16:03:15 +0900
Processing by PollsController#create as HTML
Parameters: {"authenticity_token"=>"[FILTERED]","poll"=>{"title"=>"Test Poll","questions_attributes"=>{"0"=>{"_destroy"=>"false","content"=>"Question 1"},"1"=> 
{"_destroy"=>"false","content"=>"Question 2"}}},"commit"=>"Create Poll"}
Rendering layout layouts/application.html.erb
Rendering polls/new.html.erb within layouts/application
Rendered polls/_question_fields.html.erb (Duration: 0.5ms | Allocations: 296)
Rendered polls/_question_fields.html.erb (Duration: 0.4ms | Allocations: 294)
Rendered polls/_question_fields.html.erb (Duration: 0.7ms | Allocations: 285)
Rendered polls/_form.html.erb (Duration: 4.1ms | Allocations: 1695)
Rendered polls/new.html.erb within layouts/application (Duration: 4.5ms | Allocations: 1804)
[Webpacker] Everything's up-to-date. nothing to do
Rendered layout layouts/application.html.erb (Duration: 92.4ms | Allocations: 8240)
Completed 422 Unprocessable Entity in 115ms (Views: 93.4ms | ActiveRecord: 0.0ms | Allocations: 10383)

解决方法

在运行 Poll 模型中的验证时未创建 Question,因此问题的 poll_idnil 导致存在验证失败。您可以移除验证,因为 belongs_to :poll 关联会验证投票是否存在 (belongs_to association is required by default from Rails 5)。

class Question < ApplicationRecord
  belongs_to :poll
  validates_presence_of :content
end

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...