在 rails 中将控制器中的操作用作另一个控制器中的过滤器
Use action from a controller as filter in another controller in rails
我正在尝试创建一个操作来检查是否允许用户执行某个操作,如果不允许,那么我想将用户重定向到 "Access Denied" 视图
这就是我当前的设置
class PermissionController < ApplicationController
def authorize(permission_id)
is_permitted = is_user_permitted(permission_id)
respond_to do |format|
format.js { render :json => {:is_permitted => is_permitted, :redirect => url_for(:controller => 'welcome', :action => 'index' , notice: "No access")}}
format.all { redirect_to :controller => 'welcome', :action => 'index' , notice: "No access" unless is_permitted == true }
end
end
结束
我想在另一个控制器的 :before_filter 中调用授权操作。
我该怎么做?
我无法将授权操作放在 ApplicationController 中,因为我想在 routes.rb
中定义此操作的路由
你为什么不尝试这样的事情,假设你有用户的 id 存储在会话中:
class ApplicationController < ActionController::Base
def current_user
return unless session[:user_id]
@current_user ||= User.find(session[:user_id])
end
def authorize
# If user is NOT permitted
if !is_user_permitted(current_user)
# Response for you ajax here
respond_to do |format|
format.js { render :json => {:is_permitted => false, :redirect => url_for(:controller => 'welcome', :action => 'index' , notice: "No access")}}
format.all { redirect_to :controller => 'welcome', :action => 'index' , notice: "No access" }
end
end
end
end
class SomeOtherChildController < ApplicationController
before_filter :authorize, :only => [:show, :new, :edit]
# or you can use :except => [:index, :create, :destroy, :update] instead of :only.
# No authorization required
def index
end
# Authorization required
def show
end
# Authorization required
def new
end
# No authorization required
def create
end
# Authorization required (Ajax response for your "Edit" button)
def edit
# authorize method in ApplicationController will be called first
# If user is authorized, then the rest of this action will be executed
respond_to do |format|
format.js { render :json => {:is_permitted => true} }
end
end
# No authorization required
def update
end
# No authorization required
def destroy
end
end
将此作为您可能想要实施的内容的大纲和一般概念。
这通常是我在我的应用程序中使用权限实现的概念。您可能不想将 Permissions 逻辑放在单独的子 class 控制器中,因为为了检查权限,您要么必须创建 PermissionsController 的引用对象(这是丑陋的,非常不 Rails 之类的)并在您尝试检查权限的任何控制器中使用它,否则您将使所有其他控制器 class 继承自 PermissionsController,这并不糟糕,但肯定不理想。
如果用户可以拥有多种类型的权限,您最好创建一个具有 User has_many Permissions
关系的权限模型和控制器,其中 authorize
方法中的逻辑会变得有点更容易实施。
@NickM 在他的评论中提到了这一点...... OtherController
继承自 PermissionController
class PermissionController < ApplicationController
def authorize
...
end
end
class OtherController < PermissionController
before_filter :authorize
end
但是我注意到你的授权方法有一个参数?
您需要在 before_filter 子句中处理它。假设您可以将 permission_id
存储在会话变量中...
class PermissionController < ApplicationController
def authorize(permission_id)
...
end
end
class OtherController < PermissionController
before_filter { |controller| controller.authorize(session[:permission_id] }
end
我正在尝试创建一个操作来检查是否允许用户执行某个操作,如果不允许,那么我想将用户重定向到 "Access Denied" 视图 这就是我当前的设置
class PermissionController < ApplicationController
def authorize(permission_id)
is_permitted = is_user_permitted(permission_id)
respond_to do |format|
format.js { render :json => {:is_permitted => is_permitted, :redirect => url_for(:controller => 'welcome', :action => 'index' , notice: "No access")}}
format.all { redirect_to :controller => 'welcome', :action => 'index' , notice: "No access" unless is_permitted == true }
end
end
结束
我想在另一个控制器的 :before_filter 中调用授权操作。
我该怎么做?
我无法将授权操作放在 ApplicationController 中,因为我想在 routes.rb
中定义此操作的路由你为什么不尝试这样的事情,假设你有用户的 id 存储在会话中:
class ApplicationController < ActionController::Base
def current_user
return unless session[:user_id]
@current_user ||= User.find(session[:user_id])
end
def authorize
# If user is NOT permitted
if !is_user_permitted(current_user)
# Response for you ajax here
respond_to do |format|
format.js { render :json => {:is_permitted => false, :redirect => url_for(:controller => 'welcome', :action => 'index' , notice: "No access")}}
format.all { redirect_to :controller => 'welcome', :action => 'index' , notice: "No access" }
end
end
end
end
class SomeOtherChildController < ApplicationController
before_filter :authorize, :only => [:show, :new, :edit]
# or you can use :except => [:index, :create, :destroy, :update] instead of :only.
# No authorization required
def index
end
# Authorization required
def show
end
# Authorization required
def new
end
# No authorization required
def create
end
# Authorization required (Ajax response for your "Edit" button)
def edit
# authorize method in ApplicationController will be called first
# If user is authorized, then the rest of this action will be executed
respond_to do |format|
format.js { render :json => {:is_permitted => true} }
end
end
# No authorization required
def update
end
# No authorization required
def destroy
end
end
将此作为您可能想要实施的内容的大纲和一般概念。
这通常是我在我的应用程序中使用权限实现的概念。您可能不想将 Permissions 逻辑放在单独的子 class 控制器中,因为为了检查权限,您要么必须创建 PermissionsController 的引用对象(这是丑陋的,非常不 Rails 之类的)并在您尝试检查权限的任何控制器中使用它,否则您将使所有其他控制器 class 继承自 PermissionsController,这并不糟糕,但肯定不理想。
如果用户可以拥有多种类型的权限,您最好创建一个具有 User has_many Permissions
关系的权限模型和控制器,其中 authorize
方法中的逻辑会变得有点更容易实施。
@NickM 在他的评论中提到了这一点...... OtherController
继承自 PermissionController
class PermissionController < ApplicationController
def authorize
...
end
end
class OtherController < PermissionController
before_filter :authorize
end
但是我注意到你的授权方法有一个参数?
您需要在 before_filter 子句中处理它。假设您可以将 permission_id
存储在会话变量中...
class PermissionController < ApplicationController
def authorize(permission_id)
...
end
end
class OtherController < PermissionController
before_filter { |controller| controller.authorize(session[:permission_id] }
end