Rails远程表单验证错误未显示。

5
我可以帮您翻译成中文。这段内容是关于在Rails 4中使用remote: true创建ajax表单的,但是存在一个问题,即验证错误无法显示在表单中。以下是当前代码库的代码:

1. 表单

= simple_form_for @foo, url: foos_path, as: :foo, remote: true do |f|

  .row
    .input-field
      = f.input :bar

  .right-align.card-button
    = f.button :submit, class: "waves-light blue", data: { disable_with: "Loading..." }

2. create.js.erb

$("#new_foo").html('<%= j render_cell :foo, :form, foo: @foo %>');

3. 控制器

def create
  @foo = FooForm.new( Foo.new )
  respond_to do |format|
    if @foo.validate(params[ :country ])
        @foo.save
        format.html { redirect_to root_path }
        format.json { render :show, status: :created, location: @foo.model }
        format.js 
    else
      format.html { render :new }
      format.json { render json: @foo.errors, status: :unprocessable_entity }
      format.js 
    end
  end
end

我期望这段代码在提交错误后显示验证错误。然而出于某种原因,在提交不正确的表单后什么也没有发生。我可以确认表单已被提交,因为提交在日志中被处理。当我删除远程提交时,我也可以确认表单完美地工作。
有什么我漏掉的吗?
PS. 我正在使用Reform宝石,这可能会使我的控制器对象代码对许多人来说有点陌生。我在我的js文件中呈现一个单元格,如此gem
更新:我已经进一步努力解决这个问题。我实施了一个解决方案,复制了我在以前的应用程序中构建的“remote:true”解决方案,原封不动地实现。这在我的以前的应用程序中无缝运行,但在我的新应用程序中没有显示验证错误。这两个应用程序之间唯一的区别是Ruby和Rails的版本。
在我第一个应用程序中运行的是Ruby: 2.2.1和Rails: 4.2.2。我的新应用程序(“我无法使其工作的应用程序”)正在运行Ruby: 2.2.3和Rails: 4.2.4。这可能会有影响吗?

我从你的回答中了解到了render_cell,谢谢你。 - Richard Peck
你能发布浏览器传输的确切HTML响应吗?有趣的是它在没有“远程”的情况下如何工作。 - Richard Peck
@RichPeck 谢谢您的回复。很高兴我能帮到您。这是一个非常好的小工具,它帮助我大大简化了我的代码。不过我还不太清楚您具体需要什么?我已经在我的问题中添加了更多细节。 - HermannHH
3个回答

6
经过多个小时的努力,我终于成功解决了这个问题。虽然不确定为什么会出现这种情况,但我在这里发布答案,以防其他人遇到类似的问题。这篇Stackoverflow答案引导我朝着正确方向前进。
我需要在我的创建操作中添加这一行:
format.js    { render layout: false, content_type: 'text/javascript' }

因此,我的完整创建操作现在看起来像这样:

def create
  @foo = FooForm.new( Foo.new )
  respond_to do |format|
    if @foo.validate(params[ :country ])
        @foo.save
        format.html { redirect_to root_path }
        format.json { render :show, status: :created, location: @foo.model }
        format.js 
    else
      format.html { render :new }
      format.json { render json: @foo.errors, status: :unprocessable_entity }
      format.js   { render layout: false, content_type: 'text/javascript' }
    end
  end
end

和你一样的问题,兄弟。我添加了remote = true,但验证未显示 - 我猜这是因为表单没有被提交。你有任何想法如何解决这个问题吗? - BenKoshy

2

它无法正常工作的原因是因为AJAX默认期望可解析的javascript作为响应,而不是json对象本身。您需要使用$.ajaxSetup进行调整,添加dataType: json,或在回调之后将'json'作为最终参数传递给$.post,以便它默认预期json。


1

从查看代码来看,唯一我发现似乎有点不对的是渲染调用。如果我理解错了,请纠正我,但目前你是否将错误作为模型对象返回,而我认为你需要提供errors键。

format.json { render json: {errors: @foo.errors}, status: :unprocessable_entity }

或者,此外,我认为如果你只返回对象本身,错误将被正确映射到对象内部的errors键中。

format.json { render json: @foo, status: :unprocessable_entity }


感谢您的尝试,@codeurge。不幸的是,仍然没有运气。我可以在我的JS控制台中看到正确的响应,但错误没有显示在我的表单中。 - HermannHH
我已经更新了我的问题并提供了更多细节。我尝试了许多方法,但仍然没有运气。 - HermannHH
鉴于您能在JS控制台上看到JSON响应中的错误,并且在HTML响应(remote:true已删除)中看到错误,您可能需要第二个意见,但我无法找到simple_form支持通过AJAX返回的错误的呈现。您可能需要将simple_form作为带有错误的JSON部分返回,并重新呈现该响应以显示DOM,或编写一些代码仅显示返回的错误。我怀疑这是因为您在两种情况下都有错误,响应之间唯一的区别是重新呈现。 - codeurge
以上建议的一个例子可以在这里看到:https://stackoverflow.com/questions/15444473/parsing-json-errors-using-simple-form-and-ajax-in-rails - codeurge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接