在 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