Rails 3:如何在Ajax调用中“redirect_to”?

提交login表单后,使用Ajax调用以下attempt_login方法。

 class AccessController < ApplicationController [...] def attempt_login authorized_user = User.authenticate(params[:username], params[:password]) if authorized_user session[:user_id] = authorized_user.id session[:username] = authorized_user.username flash[:notice] = "Hello #{authorized_user.name}." redirect_to(:controller => 'jobs', :action => 'index') else [...] end end end 

问题是redirect_to不起作用。

你将如何解决这个问题?

最后,我刚换了

 redirect_to(:controller => 'jobs', :action => 'index') 

有了这个:

 render :js => "window.location = '/jobs/index'" 

它工作正常!

有一个非常简单的方法来保持下一个请求的闪光灯。 在你的控制器中做类似的事情

 flash[:notice] = 'Your work was awesome! A unicorn is born!' flash.keep(:notice) render js: "window.location = '#{root_path}'" 

flash.keep将确保闪存保留下一个请求。 所以当渲染root_path时候,它会显示给定的flash消息。 Rails是真棒:)

我觉得这样稍微好一些:

render js: "window.location.pathname='#{jobs_path}'"

在我的一个应用程序中,我使用JSON来进行redirect和Flash消息数据。 它看起来像这样:

 class AccessController < ApplicationController ... def attempt_login ... if authorized_user if request.xhr? render :json => { :location => url_for(:controller => 'jobs', :action => 'index'), :flash => {:notice => "Hello #{authorized_user.name}."} } else redirect_to(:controller => 'jobs', :action => 'index') end else # Render login screen with 422 error code render :login, :status => :unprocessable_entity end end end 

简单的jQuery示例将是:

 $.ajax({ ... type: 'json', success: functon(data) { data = $.parseJSON(data); if (data.location) { window.location.href = data.location; } if (data.flash && data.flash.notice) { // Maybe display flash message, etc. } }, error: function() { // If login fails, sending 422 error code sends you here. } }) 

结合所有最好的答案:

 ... if request.xhr? flash[:notice] = "Hello #{authorized_user.name}." flash.keep(:notice) # Keep flash notice around for the redirect. render :js => "window.location = #{jobs_path.to_json}" else ... 
 def redirect_to(options = {}, response_status = {}) super(options, response_status) if request.xhr? # empty to prevent render duplication exception self.status = nil self.response_body = nil path = location self.location = nil render :js => "window.location = #{path.to_json}" end end 

我不想修改我的控制器操作,所以我想出了这个黑客:

 class ApplicationController < ActionController::Base def redirect_to options = {}, response_status = {} super if request.xhr? self.status = 200 self.response_body = "<html><body><script>window.location.replace('#{location}')</script></body></html>" end end end