在我的应用程序中,我将用户的ID存储在session []中。在每个控制器动作开始时,我正在调用ApplicationController中定义的一个名为current_user的方法:
def current_user
@current_user ||= session[:current_user_id] &&
User.find_by_id(session[:current_user_id])
end
在我的控制器方法的开头,我有以下内容:
@current_user = current_user
if @current_user == nil
redirect_to :home
return
end
这显然是重复的代码,应该是某个方法。我读了答案for this question,并尝试将我的方法放入我的控制器类现在来自的父类中,但是现在我似乎无法从该方法重定向。
在我的父班上,我有:
def verify_user
user = current_user
if user == nil
redirect_to "/"
return
end
return user
end
现在我已将控制器方法更改为:
@current_user = verify_user
这不起作用,我想我知道为什么。首先,我不能简单地在我的verify_user方法中调用return,因为这显然只会返回到控制器。重定向似乎没有任何影响,可能是因为在重定向调用之后调用了format.html,这是原始代码返回的原因。
那么,我在这里做错了什么,你有什么建议要解决它?这是错误的方法吗?我的主要目标是保持整个“检查用户是否登录,否则重定向”到每个控制器方法的一行代码。
答案 0 :(得分:2)
看看设计宝石https://github.com/plataformatec/devise。它为您处理了许多这种基本的用户身份验证逻辑。我们可以通过将before_filter :authenticate_user!
添加到需要保护的控制器或操作来解决这个特定问题。
答案 1 :(得分:1)
将以下逻辑添加到ApplicationController
类:
class ApplicationController < ActionController::Base
def current_user
...
end
def logged_in?
current_user.present?
end
def require_user
return true if logged_in?
render_error_message("You must be logged in to access this page",
new_user_session_url)
return false
end
def render_message message
respond_to do |format|
format.html {
if request.xhr?
render(:text => message, :status => :unprocessable_entity)
else
redirect_to(root_url, :notice => message)
end
}
format.json { render :json => message, :status => :unprocessable_entity }
format.xml { render :xml => message, :status => :unprocessable_entity }
end
end
end
现在向您的控制器添加before_filter
:
class OrdersController < ApplicationController
before_filter :require_user
end