2011-05-17 31 views
0

我有一个“文章”脚手架项目 - 其中包括缩略图的回形针文件字段 - 团队中的其他人抱怨他们是如何在提交表单时再次将该文件添加到该字段,并且由于其他字段上的数据缺失而导致验证错误被触发。Ruby on Rails:找出406错误/缺乏重定向的AJAX化形式

认为这是由于浏览器的限制,我添加了一个remote => true以及一个error.js.erb文件,如果页面没有被重新加载,则确定文件字段将会持续存在。不幸的是,事实并非如此,因为我读到浏览器出于安全原因无法通过AJAX处理多部分表单/文件。然而,我然后发现了解决这个问题的Remotipart gem。所以,我的应用程序的相关部分看起来如下...

_form.html.erb

<%= form_for(@article, :html => { :multipart => true }, :remote => TRUE) do |f| %> 
    <div id="errors"></div> 
    <%= f.text_field :title %> 
    <%= f.text_area :body %> 
    <%= f.file_field(:photo) %> 
    <%= f.submit %> 
<% end %> 

articles_controller.rb(创建操作)

def create 
    @article = Article.new(params[:article]) 

    respond_to do |format| 
     if @article.save 
     format.html { redirect_to(@article, :notice => 'Article was successfully created.') } 
     format.xml { render :xml => @article, :status => :created, :location => @article } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @article.errors, :status => :unprocessable_entity } 
     format.js { render 'errors', :locals => { :item => @article } } 
     end 
    end 
    end 

错误.js.erb

<%= remotipart_response do %> 
    $("#errors").empty().append('<div id="error_explanation"><h2><%= pluralize(item.errors.count, "error") %> prohibited this article from being saved:</h2><ul></ul></div>'); 
    <% item.errors.full_messages.each do |msg| %> 
     $("#error_explanation ul").append("<li><%= escape_javascript(msg) %></li>"); 
    <% end %> 
<% end %> 

所以基本上,如果有验证错误,js文件将这些错误添加到窗体上的错误div。此外,如果填充的话,文件字段仍然存在。它可以工作:它可以在数据库中创建内容并上传文件,或者在验证失败的情况下抛出错误而不会丢失文件字段,但仍然存在一个问题。

当表单与上传的文件一起提交时,我的日志中出现406不允许的错误,但没有重定向到显示页面。如果表单没有上传文件,则日志将返回200 OK,但该页面也不会重定向到show操作。

打猎谷歌和其他SO线程后,我发现这段代码,理应将它传递正确的标题(是的,安装jQuery和application.js中之前运行)...

应用.js

jQuery.ajaxSetup({ 
    'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} 
}) 

...不幸的是它不起作用。我出来的想法,有关如何击败406问题,并使其正确重定向的任何建议?

回答

0

一直没能要回来这个问题到现在为止,但我终于解决了这一点。首先,我放弃了application.js代码。其次,406重定向是通过在respond_to代码的一个format.js保存成功解决...

respond_to do |format| 
    if @article.save 
    format.js 
    format.html { [...] } 
    else 
    [...] 
    end 
end 

唯一的问题是,该网页将不会重定向可言,即使redirect_to的摆在了格式。 JS。它确实触发了一个create.js.erb文件,因此,我把...

window.location.replace("/articles"); 

...在加载create.js.erb时启动重定向。我宁愿它通过控制器响应和重定向,而不是JavaScript重定向,但我还没有看到这个问题的一个工作解决方案(我研究的任何涉及request.xhr代码的东西都根本不起作用)。但是,这工作。

然而,一个附带的好处,以这种方式做的是,我可以得到保存的文章更有创意,比如重定向到文章索引之前预览几秒钟的“显示”页面等

0

我认为你这样做太复杂了,为什么不把重点放在防止用户在第一次出现错误之后再次上传文件。用户继续他们的快乐方式,你不必乱糟糟的JavaScript黑客。

存储文件和用户重定向到一个创建页已填充文件中的字段。