0

私は「Article」足場 (サムネイル用のペーパークリップ ファイル フィールドを含む) を含むプロジェクトを持っています。チームの他のメンバーは、フォームを送信したときにフィールドにファイルを再度追加する方法について不満を漏らしており、検証エラーが発生します。別のフィールドのデータが欠落しているためにトリガーされました。

これはブラウザーの制限によるものだと考えて、フォームに 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 %>

article_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 に追加します。さらに、ファイル フィールドは、入力されている場合は保持されます。すべて機能します。データベースにコンテンツを作成してファイルをアップロードするか、検証に失敗した場合にファイル フィールドを失うことなくエラーをスローしますが、1 つの問題が残ります。

ファイルをアップロードしてフォームを送信すると、ログに 406 not allowed エラーが表示され、ショー ページにリダイレクトされません。フォームにファイルがアップロードされていない場合、ログは 200 OK を返しますが、ページも show アクションにリダイレクトされません。

Googleや他のSOスレッドを探した後、正しいヘッダーを渡すと思われるこのコードを見つけました(そして、jQueryがインストールされ、application.jsの前に実行されます)...

アプリケーション.js

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

・・・残念ながら使えません。私はアイデアがありません.406の問題を打ち負かし、これを適切にリダイレクトする方法についての提案はありますか?

4

2 に答える 2

0

これを複雑にしすぎていると思います。最初にエラーが発生した後、ユーザーがファイルを再度アップロードできないようにすることに集中してください。ユーザーは楽しい道を歩み続けており、醜い JavaScript ハックをいじる必要はありません。

ファイルを保存し、ファイル フィールドが入力された作成ページにユーザーをリダイレクトします。

于 2011-05-17T22:44:10.220 に答える
0

今までこの問題に戻ることができませんでしたが、ついにこれを解決しました。まず、application.js コードを削除しました。次に、406 リダイレクトは、respond_to の保存成功に format.js を含めることで解決されました...

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

唯一の問題は、redirect_to が format.js に配置されていても、ページがまったくリダイレ​​クトされないことです。それはcreate.js.erbファイルをトリガーしたので、その中に入れました...

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

...create.js.erb のロード時にリダイレクトを開始します。JavaScriptリダイレクトではなく、コントローラーを介して応答およびリダイレクトすることをお勧めしますが、この問題に対する有効な解決策をまだ見ていません(request.xhrコードに関連して調査した他のものはまったく機能しませんでした)。しかし、これは機能します。

ただし、このようにすることの副次的な利点は、記事のインデックスにリダイレクトする前に「表示」ページを数秒間プレビューするなど、記事を保存してよりクリエイティブになることです。

于 2011-07-19T16:02:20.507 に答える