Rails:如果表单返回验证错误,则保持 JSON 表单字段填充

Posted

技术标签:

【中文标题】Rails:如果表单返回验证错误,则保持 JSON 表单字段填充【英文标题】:Rails: Keep JSON form fields populated if the form returns a validation error 【发布时间】:2021-01-28 15:51:01 【问题描述】:

我有一个创建产品的 Rails 简单表单,我在表单中有以下三个字段,以便将产品与适当的类别相关联:

 <div class="form-group">
   <%= f.input :child_category_id, :collection => @categories.order(:name), :label_method => :name, :value_method => :id, label: "Category", :include_blank => "--Select Category--", input_html:  id: "first_dropdown"  %>
 </div>

 <div class="show_hide">
   <%= f.input :subcategory_id, :collection => [] || @subcategory.order(:name), :label_method => :name, :value_method => :id, label: false, :include_blank => "--Select Category--", input_html:  id: "second_dropdown"  %>
 </div>

 <div class="show_hide_third">
   <%= f.input :child_subcategory_id, :collection => [] || @child_subcategory.order(:name), :label_method => :name, :value_method => :id, label: false, input_html:  id: "third_dropdown"  %>
 </div>

这是路线:

resources :products, :path => "products/select_item", only: [:select_item] do
  get :select_item, on: :collection
end

这是我拥有的控制器内部的方法:

def select_item
  if params[:child_category_id].present?
    @subcategory = Subcategory.where(child_category_id: params[:child_category_id])
    render :json => @subcategory.order(:name)
  end
  if params[:subcategory_id].present?
    @child_subcategory = ChildSubcategory.where(subcategory_id: params[:subcategory_id])
    render :json => @child_subcategory.order(:name)
    end
end

这是我在控制器内部的新产品和创建产品方法:

def new; end

def create
  @product = Product.new(product_params)
    respond_to do |format|
      if @product.save
        format.html  redirect_to root_path 
        format.json  render :new, status: :created, location: @product 
        flash[:success] = "Product was successfully added."
      else
        format.html  render :new 
        format.json  render json: @product.errors, status: :unprocessable_entity 
      end
    end
end 

这是我用来根据所选值填充第二个和第三个字段的 javascript

    $('#first_dropdown').on('change', function() 
        $.ajax(
            url: '/products/select_item/select_item?child_category_id=' + $(this).val(),
            dataType: 'json',
            success: function(data) 
                let childElement = $('#second_dropdown');
                if( data.length === 0 ) 
                    $('.show_hide').hide();
                    $('.show_hide_third').hide();
                 else 
                    $('.show_hide').show();
                
                childElement.html('');
                data.forEach(function(v) 
                    let id = v.id;
                    let name = v.name;
                    childElement.append('<option value="' + id + '">' + name + '</option>');
                );
            
        );
    );

    $('#second_dropdown').on('change', function() 
        $.ajax(
            url: '/products/select_item/select_item?subcategory_id=' + $(this).val(),
            dataType: 'json',
            success: function(data) 
                let childElement = $('#third_dropdown');
                if( data.length === 0 ) 
                    $('.show_hide').hide();
                    $('.show_hide_third').hide();
                 else 
                    $('.show_hide').show();
                    $('.show_hide_third').show();
                
                childElement.html('');
                data.forEach(function(v) 
                    let id = v.id;
                    let name = v.name;
                    childElement.append('<option value="' + id + '">' + name + '</option>');
                );
            
        );
    );

一切正常,所有字段都正确填充。我遇到的唯一问题是,当表单再次呈现时,由于验证错误,JSON 字段显示为空,即使它们已正确填充。即使表单返回验证错误,如何保持 JSON 表单字段填充?

【问题讨论】:

【参考方案1】:

问题在于,在页面加载时,您的下拉列表中没有可供选择的选项;因此表单无法选择正确的值。你需要像这样更新你的控制器:

def create
  @product = Product.new(product_params)
    respond_to do |format|
      if @product.save
        format.html  redirect_to root_path 
        format.json  render :new, status: :created, location: @product 
        flash[:success] = "Product was successfully added."
      else
        @categories = Category.all.order(:name)
        @subcategory = Subcategory.where(child_category_id: @product.child_category_id).order(:name)
        @child_subcategory = ChildSubcategory.where(subcategory_id: @product.subcategory_id).order(:name)
        format.html  render :new 
        format.json  render json: @product.errors, status: :unprocessable_entity 
      end
    end
end

【讨论】:

感谢@TomDunning 的帮助......它工作得很好! :)))) 没问题,很高兴我能帮助@Dev :) @Dev 如果可以选择编辑,您可能希望在编辑和更新时使用相同的内容。 我刚刚对编辑和更新进行了更改....再次感谢!!

以上是关于Rails:如果表单返回验证错误,则保持 JSON 表单字段填充的主要内容,如果未能解决你的问题,请参考以下文章

渲染 json 未显示在 rails 4 的视图中

GraphQL 和表单验证错误

如果 Rails 表单中的另一个字段为空,则验证嵌套字段

Rails API - 无法创建用户,密码是FILTERED并返回所有验证错误

Rails 为重复的 JSON 请求自动更新 CSRF 令牌

从 GraphQL-Java 返回错误