Rails 3: Como “redirect_to” na chamada do Ajax?

O seguinte método attempt_login é chamado usando o Ajax após o attempt_login um formulário de login.

 class AccessController  'jobs', :action => 'index') else [...] end end end 

O problema é que o redirect_to não funciona.

Como você resolveria isso?

Finalmente, acabei de replace

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

com isso:

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

e funciona bem!

Existe uma maneira muito fácil de manter o flash para o próximo pedido. No seu controlador, faça algo como

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

O flash.keep garantirá que o flash seja mantido para a próxima solicitação. Então, quando o root_path é renderizado, ele mostrará a mensagem flash fornecida. Rails é incrível 🙂

Eu acho que isso é um pouco melhor:

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

Em um dos meus aplicativos, uso o JSON para transmitir os dados de redirecionamento e de mensagem flash. Seria algo parecido com isto:

 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 

E simples exemplo de jQuery seria:

 $.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. } }) 

Combinando o melhor de todas as respostas:

 ... 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 

Eu não queria modificar minhas ações do controlador, então eu criei este hack:

 class ApplicationController < ActionController::Base def redirect_to options = {}, response_status = {} super if request.xhr? self.status = 200 self.response_body = "" end end end