我试图根据角色和“帖子”控制器锁定一些控制器,无论他们是否分配了任何权限。这似乎有效,但我想知道是否有一个干净的方法来处理这个问题。这就是我在应用程序控制器中所拥有的,我称之为前置过滤器......
if controller_name == 'users' || 'accounts'
unless @current_user.master? || @current_user.power?
render :template => "layouts/no_content"
end
elsif controller_name == 'posts'
unless @current_user.permissions.count > 0
render :template => "layouts/no_content"
end
end
提前致谢。
答案 0 :(得分:7)
您不应该创建一个代码片段来检查控制器名称,以便在application.rb中执行特定操作。您应该在仅在需要它们的控制器中的过滤器之前定义
在ApplicationController中创建2个方法:
private
def require_master_or_power_user
unless @current_user.master? || @current_user.power?
render :template => "layouts/no_content"
end
end
def require_some_permisions
unless @current_user.permissions.count > 0
render :template => "layouts/no_content"
end
end
现在将其添加为您需要的前置过滤器:
class UsersController < ApplicationController
before_filter :require_master_or_power_user
...
end
class AccountsController < ApplicationController
before_filter :require_master_or_power_user
...
end
class PostsController < ApplicationController
before_filter :require_some_permisions
...
end
因此ApplicationController定义了过滤器,但是它是否适用于其他控制器是否实际使用这些过滤器。像ApplicationController这样的超类应该永远不会根据其子类有条件地分支执行。选择何时使用提供的行为是您想要首先进行子类化的原因之一。
从代码可读性的角度来看,它也更加清晰。在查看UsersController时,很明显当你看到一个名为“require_something”之类的过滤器时会发生一些权限。根据您的方法,您无法通过查看用户控制器代码本身来判断这一点。
答案 1 :(得分:1)
我强烈建议您遵守MVC和OOP,并将尽可能多的用户相关逻辑移回用户模型,如下所示:
class User < ActiveRecord::Base
def has_permission?
true if self.master? || self.power? || (self.permissions.count > 1)
end
然后你可以在application.rb中使用一个过滤器:
protected
def check_template
render :template => "layouts/no_content" if current_user.has_permission? == true
end
并使用Squeegy建议的before_filter调用它,在相应的控制器中,或者在application_controller.rb中的站点范围内
before_filter :check_template
如果你决定改变给予人们许可的范围,这种方法显然有点清洁,而且不那么脆弱,你只需要在应用程序范围内进行一次更改。
答案 2 :(得分:0)
我建议您使用ACL系统:http://github.com/ezmobius/acl_system2
答案 3 :(得分:0)
一个简短的小手写DSL。甚至没有检查代码的语法错误,但你会得到图片。在您的应用程序控制器中:
before_filter :handle_requirements
def self.requirement(*controllers, &block)
@_requirements ||= {}
@_requirements[controllers] = block
end
def handle_requirements
return unless @_requirements
@_requirements.each do |controllers, proc|
if controllers.include?(controller.controller_name)
restrict_access unless instance_eval(&block)
end
end
end
def restrict_access
render :template => "layouts/no_content"
end
用法(也在您的应用程序控制器中)
requirement('users', 'accounts') do
@current_user.master? || @current_user.power?
end
或者,只需使用ACL系统Radar提及。
答案 4 :(得分:0)
值得一看的另一个插件是role requirement,我一直在使用它。我认为他们都可以做大致相同的事情。
答案 5 :(得分:0)
这是RESTful_ACL的插件;我开发的ACL插件/ gem,并且被广泛使用。它让您可以自由地按照自己的意愿设计角色,而且非常透明。