2011-05-17 35 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黑客。

存儲文件和用戶重定向到一個創建頁已填充文件中的字段。