Следующий метод attempt_login
вызывается с использованием Ajax после отправки формы входа.
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
не работает.
Как бы вы решили это?
Ответ 1
Наконец, я просто заменил
redirect_to(:controller => 'jobs', :action => 'index')
с этим:
render :js => "window.location = '/jobs/index'"
и он отлично работает!
Ответ 2
Существует очень простой способ сохранить флэш для следующего запроса. В контроллере сделайте что-то вроде
flash[:notice] = 'Your work was awesome! A unicorn is born!'
flash.keep(:notice)
render js: "window.location = '#{root_path}'"
flash.keep
будет следить за тем, чтобы вспышка сохранялась для следующего запроса.
Поэтому, когда отображается root_path
, он отображает данное флэш-сообщение. Rails - потрясающий:)
Ответ 3
Я думаю, что это немного лучше:
render js: "window.location.pathname='#{jobs_path}'"
Ответ 4
В одном из моих приложений я использую JSON для переноса данных перенаправления и флэш-сообщений. Он будет выглядеть примерно так:
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.
}
})
Ответ 5
Сочетание лучших ответов:
...
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
...
Ответ 6
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
Ответ 7
Я не хотел изменять свои действия с контроллером, поэтому я придумал этот взлом:
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