我有一个基于登录用户在两个不同“上下文”中运行的控制器(基本上,用户可以在自己的帐户上执行CRUD操作,管理员用户可以CRUD所有用户帐户;操作是相同的在上下文之间,但权限是不同的。)
为了促进这一点,我编写了一个before过滤器,用于检查上下文并在过滤之前附加正确的特定于上下文的权限:
def ensure_logged_in
if user_context?
self.class.append_before_filter :authorize_user
else
self.class.append_before_filter :authorize_admin
end
end
此外,ensure_logged_in
仅针对特定操作调用:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
这在开发模式下工作得很好,但是一旦代码处于生产状态,我们就开始遇到奇怪的行为(即,要求用户登录以获取不需要登录的操作;有几个打开的视图操作在控制器中。)
我的猜测是因为开发会重新加载每个页面命中的类,append_before_filter
调用仅适用于该页面命中,但由于生成缓存类,调用append_before_filter
会将其附加到控制器的后续使用中。这是一个有效的假设吗?如果是这样,我该怎么办呢?
答案 0 :(得分:2)
我的猜测是因为开发会重新加载每个页面命中的类,所以append_before_filter调用仅适用于该页面命中,但由于生成缓存类,调用append_before_filter会将其附加到控制器的后续使用中。这是一个有效的假设吗?如果是这样,我该怎么做呢?
您在此处的陈述完全正确。在生产中,您不能更改类上的过滤器链,因为类是持久的,因此如果您更改过滤器链,那么现在将影响该控制器类从该点开始处理的每个请求。我会使用一个普通的before filter方法,根据user_context?
调用其中一个像这样:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
def ensure_logged_in
if user_context?
return authorize_user
else
return authorize_admin
end
end