AJAX表单(使用simple_form)保留错误validation

这可能是我提出的更困难的问题之一,但我已经被困了几天,我认为最好是从更有经验的rails社区获得支持。

我正在开发一个虚拟应用程序,大致遵循本指南… ajax / jquery教程 …

制作我自己的自定义,指南帮助我创建了一个“品牌”(包括嵌套模型“模型”,“子模型”和“风格”)提交表单(使用simple_form)和品牌列表在同一页面上..这完美地工作,并且强制执行validation(对于我的模型)。但是,当我将表单和品牌列表放在同一页面上时,我会丢失在提交失败时出现的整洁的内联validation错误(请参见下图)。 无法让内联错误发挥作用让我意识到我还有更多关于渲染的知识..这就是为什么我注重找到这个问题的答案

在此处输入图像描述

……这是列表:

在此处输入图像描述

下面是索引操作的控制器:

def index #This is for the product listing @brands = Brand.all.reverse #This is for the form @brand = Brand.new @model = Model.new @submodel = Submodel.new @style = Style.new respond_to do |format| format.html end end 

上面的表单创建了在嵌套提交表单中使用的品牌,型号,子模型和样式……以下是表单的代码:

  { :class => 'form-horizontal' }, :remote => true do |m| %> 
'Brand' %> 'Model' %> 'Submodel' %> 'Style' %>
'btn btn-primary' %> 'btn' %>

现在您可以看到我正在使用:remote => true …我希望表单创建新的“品牌”,或者表单重新加载内联validation错误。 目前我的创建动作如下:

 def create @brand = Brand.new(params[:brand]) respond_to do |format| if @brand.save format.html { redirect_to brands_url, notice: 'Brand was successfully created.' } format.json { render json: @brand, status: :created, location: @brand } format.js else format.html { render action: "index" } format.json { render json: @brand.errors, status: :unprocessable_entity } format.js { render 'reload' } end end end 

if @brand.save下面出现的代码似乎if @brand.save ……但是“else”下面的代码不能按我喜欢的方式工作。 那么当@brand不保存时会发生什么? 我相信索引操作中的代码正在运行,然后@brand.errors转换为json(我假设是为了simple_formvalidation错误),然后运行reload.js.erb ..

在尝试重新加载表单(带有validation错误)时,我放了$("#entryform").load(location.href+" #entryform>*","");$("#entryform").load(location.href+" #entryform>*",""); into reload.js.erb …当我将无效数据放入我的表单时,正在调用reload.js.erb,但所有发生的情况是表单字段重新加载空白,而不是输入数据和内联validation错误。

我希望我已经提供了足够的信息来获得帮助..真的在这个问题上挣扎。 谢谢!

我认为你可以通过将表单放在一个部分(我们称之为simple_form )并将此代码放在reload.js.erb中来简化这个:

 $("#entryform").html("<%= escape_javascript(render :partial => 'simple_form') %>"); 

我不熟悉jQuery的load方法,但我认为它会执行第二次请求。 具有渲染错误的键是您正在使用的实例变量( @brand ),而渲染表单必须与您尝试在创建中保存的表单相同,因此您可以检查其上的错误。 这就是为什么在想要渲染错误时总是使用render而不是redirect_to 。 如果进行重定向,则会启动新请求,这意味着@brand会重新初始化。 我假设你的$(...).load(...)有同样的问题。

感谢您对此问答的所有问答。 它救了我。

简化@ tsherif的文件结构一个等级(假设你已经有一个js文件),我通过直接在表单上调用render并通过javascript / coffeescript显示它来解决这个问题。

 #immediate_controller def action_with_modal @brand = params[:failed_brand] || Brand.new end #brands_controller def create @brand = Brand.new(params[:brand]) respond_to do |format| if @brand.save ... else params[:failed_brand] = @brand ... format.js { render 'simple_form' } end end end #coffeescript $('form-selectors-here').on 'ajax:error', @reRegister reRegister: (e, data) => $("div-that-contains-form").html(data.responseText) 

检查一下:调用.html(…)将复制表单包装器div。 使用.replateWith(…)代替=]