我看了一些解决方案,但没有一个对我有效。我有一个表单,可以创建固定数量的嵌套对象(5次)。它工作正常,但问题是当出现验证错误时:表单显示时没有5个嵌套对象。我可以在控制器上重建对象,但这会使它们的值为空,替换用户输入,因此这是不可取的。
我的模型:
class Question < ApplicationRecord
belongs_to :question_status
belongs_to :user
has_many :choices
accepts_nested_attributes_for :choices, reject_if: proc { |attributes| attributes[:content].blank? }, limit: 5
validates :content, :source, presence: true
validate :check_number_of_choices,
def check_number_of_choices
if self.choices.select{|c| c.content.present?}.size != 5
self.errors.add :choices, I18n.t("errors.messages.number_of_choices")
end
end
end
我的看法是:
<%= form_with(model: question, local: true) do |form| %>
<% if question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :content %>
<%= form.text_area :content %>
</div>
<div class="field">
<%= form.label :source %>
<%= form.text_field :source %>
</div>
<div class="field">
<%= form.label :year %>
<%= form.number_field :year %>
</div>
<div class="field">
<%= form.label :choices %>
<%= form.fields_for :choices do |choice| %>
<p>
- <%= choice.text_field :content %>
</p>
<% end %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
我的控制器:
class QuestionsController < ApplicationController
before_action :set_question, only: [:show, :edit, :update, :destroy]
# GET /questions
# GET /questions.json
def index
@questions = Question.all
end
# GET /questions/1
# GET /questions/1.json
def show
end
# GET /questions/new
def new
@question = Question.new
5.times { @question.choices.build }
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.json
def create
@question = Question.new(question_params)
@question.question_status = QuestionStatus.find_or_create_by(name: "Pending")
@question.user = current_user
respond_to do |format|
if @question.save
format.html { redirect_to @question, notice: 'Question was successfully created.' }
format.json { render :show, status: :created, location: @question }
else
format.html { render :new }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /questions/1
# PATCH/PUT /questions/1.json
def update
respond_to do |format|
if @question.update(question_params)
format.html { redirect_to @question, notice: 'Question was successfully updated.' }
format.json { render :show, status: :ok, location: @question }
else
format.html { render :edit }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
# DELETE /questions/1
# DELETE /questions/1.json
def destroy
@question.destroy
respond_to do |format|
format.html { redirect_to questions_url, notice: 'Question was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_question
@question = Question.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit(:content, :source, :year, :question_status_id, :user_id, choices_attributes: [:id, :content])
end
end
我将感谢任何帮助。谢谢