代码之家  ›  专栏  ›  技术社区  ›  Ronan Lopes

Rails嵌套对象在验证失败时消失

  •  0
  • Ronan Lopes  · 技术社区  · 8 年前

    我看了一些解决方案,但没有一个对我有效。我有一个表单,可以创建固定数量的嵌套对象(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
    

    我将感谢任何帮助。谢谢

    1 回复  |  直到 8 年前
        1
  •  0
  •   Ronan Lopes    8 年前

    我的答案是: