2012-04-01 16 views
9

私はremote => trueのフォームを持っています。動作しますが、非常に不器用な感じ成功したAjaxフォームへのリダイレクト

# POST /items 
    # POST /items.json 
    def create 
    @item = @store.items.build(params[:item]) 

    respond_to do |format| 
     if @item.save 
     format.html { redirect_to edit_admin_item_path(@item), :flash => {:success => "#{@item.name} was successfully created."} } 
     format.js { render :js => "window.location.href = ('#{edit_admin_item_path(@item)}');"} 
     format.json { render json: @item, status: :created, location: @item } 
     else 
     format.html { render action: "new" } 
     format.js { render :partial => 'fail_create.js.erb', :locals => { :ajax_errors => @item.errors.full_messages } } 
     format.json { render json: @item.errors, status: :unprocessable_entity }  
     end 
    end 
    end 

: そして今、私のコントローラは次のようになります。それはまた私に実際に悲しい時であるフラッシュ通知を使用させることを許さない。

理想的には、私は単に「format.js {redirect_toを...}使用するか、リクエストヘッダとredirect_toに対してチェックすることができる必要がありますように感じる。ったく!

私は最善の解決策が何であるかわからないんだけどどんなアドバイスもすばらしいことですが、事前に感謝しています。

- PS - 私はこの前に多少尋ねられましたが、役に立たないことを知っています:How to redirect after a successful AJAX form submission

+0

おそらく私は何かが欠けているかもしれませんが、ページロードを必要としないAJAXフォームの提出の要点ではありませんか?あなたがリダイレクトするつもりなら、昔ながらの提出だけでなく、 – jimw

+0

ajaxは、検証と重複レコードのチェックに使用されます。次に、エラーメッセージを更新します。 フォームが成功したら、私はedit_pathにリダイレクトしたいと思っています。画像のアップロードやその他の作業が進行中です。 – Galaxy

+0

右ですが、AJAXの提出なしでJSフォームの検証を行うことができます。私がAJAX経由で提出することがわかっている唯一の理由は、ページの読み込みを避けることです。 – jimw

答えて

5

これは不可能かもしれないと思います。 Ajaxリクエストに対する応答は、XMLHttpRequestによって処理されます。 3xx応答が返された場合、URLが同じ起点の場合、XMLHttpRequestはリダイレクト自体に従います。どのようにヘッダーを設定しても、ブラウザーはそれを認識できません。だから唯一の方法は、いくつかのJavaScriptでwindow.locationを変更することでした。

+0

ヘッダーを設定することは、私が元気にしたかったものでした。それができないように見えます! – Galaxy

+2

ヘッダーを設定するのはRailsの方法ではありません。したがって、私はそのルートに行くことをお勧めしません。 –

+0

私は現在、 'make_resourceful'を使用していますが、' create'の後にユーザーを正しい場所にリダイレクトすることができません。 'response_for(:create)do | format |'外出。 サンプルコントローラコード? @AaronGray – LearningROR

3

私はRails respondersの組み合わせを使用して私の応答メッセージを生成し、いくつかのコンテン私の<action>.jsファイルのt。異なる方法が(私の場合、私のApplicationHelperに)いくつかのヘルパーで定義されている

// Checks if the article slug has changed. 
// If it has the entire page should be reloaded at that new location. 
<%= reload_if_slug_changed @article, params[:id] %> 

// Displays the flash notices 
// See ApplicationHelper#js_flash_response 
<%= js_flash_response %> 

: -

の内容はupdate.jsは次のようになりますと言います。

def js_flash_response 
    if flash.now[:notice].present? 
    js = "$('#notice').html('#{flash.now[:notice]}').change();" 
    elsif flash.now[:alert].present? 
    js = "$('#alert').html('#{flash.now[:alert]}').change();" 
    end 
end 

def reload_if_slug_changed object, expected_value 
    "window.location.href = '#{url_for [:edit, object]}';" if object.slug != expected_value 
end 

フラッシュメッセージの内容は、Rails respondersによって自動的に生成され、確実に、フラッシュ・ハッシュから削除now範囲で表示されるユーザリロードする場合(後に次のように異なる方法の内容でありますフラッシュが表示されている)、再表示されません。

私はあなたがいつもクリティカルリダイレクトを期待しているので、安心してcreateアクションをリモートで行うようにしてはいけないと思います。私のケースでは、URLスラッグが変更された場合のみリダイレクトする必要があります。

これが役立つことを願っています。それは解決策ではなく、私が同じ問題のいくつかを処理した方法です。

よろしくお願いいたします。

3

あなたのシナリオでは、コントローラのアクションからページにJavaScriptを挿入する方法は次のとおりです。あなたはこのようなあなたのアクションの挿入何かのロジック部を完了した後:

render :update do |page| 
    page << "javascript_here" 
end 

これは、あなたがwindow.locationの挿入またはJavaScriptフラッシュ法を作成したときにあなたの方法を正しく実行作成し、それを呼び出すことができるようにすべきです。

コントローラの処理をDRYする場合は、this Railscast about make_resourcefulを調べることをおすすめします。 Make_resourcefulは、各アクションの各コアアクティビティーを自動的に実行します。before :createafter :createresponse_for :create、およびafter :create_failsのように、作成したフックをタップすることもできます。この宝石を使うことで、メソッドの成功または失敗に基づいてコードを実行し、それらを細かく制御することができます。

さらに、ビューファイルにcreate.js.erbとcreate_fails.js.erbを初期化し、コントローラで何も渡されずにformat.jsをインクルードし、Railsが自動的にコントローラアクションが正常に実行されたかどうかに応じて、javascriptを含むファイルを実行します。

関連する問題