将控制器中的操作用作导轨中另一个控制器中的过滤器

时间:2016-03-19 21:17:42

标签: ruby-on-rails before-filter

我正在尝试创建一个操作,检查用户是否被允许执行某个操作,如果用户不是,那么我想将用户重定向到“拒绝访问”视图 这就是我目前的设置

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中定义到此操作的路由

2 个答案:

答案 0 :(得分:0)

为什么不尝试这样的事情,假设您在会话中存储了用户的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逻辑放在一个单独的子类控制器中,因为为了检查权限,你要么必须创建PermissionsController的引用对象(这很丑陋,非常像非Rails一样)并在你试图检查权限的任何控制器中使用它,或者你将从PermissionsController继承所有其他控制器类,这不是很糟糕,但肯定不理想。

如果用户可以拥有多种类型的权限,那么最好创建一个具有User has_many Permissions关系的权限模型和控制器,其中authorize方法中的逻辑会变得更容易实施

答案 1 :(得分:0)

@NickM在评论中对此进行了介绍...... OtherController继承自PermissionController

class PermissionController < ApplicationController
  def authorize
    ...
  end
end

class OtherController < PermissionController
  before_filter :authorize
end

但是我注意到你的authorize方法有一个参数?

您需要在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