如何将参数发送到之前的filter?

我想在我的应用程序控制器中创建一个before_filter方法,就像这样……

def check_role(role_name) unless logged_in_user.has_role? role_name flash[:notice] = 'Access to that area requires additional privileges.' redirect_to :back end end 

但是,在filter可以获取参数之前,它看起来并不像。

有没有办法参数化这个调用,或者我是否想用锤子驱动螺丝?

您应该可以使用块来执行此操作:

 before_filter {|controller| controller.check_role('admin') } 

您可以使用一些元编程。 像这样的东西(完全没有经过测试,只是为了让你知道它会如何发展):

 Module RoleWithIt Role.all.each do |role| define_method("check_#{role.name}_role".to_sym) do check_role(role.name) end end def check_role(role_name) return if logged_in_user.has_role?(role_name) flash[:notice] = 'Access to that area requires additional privileges.' redirect_to :back end end ApplicationController.send :include, RoleWithIt 

要在应用程序初始化时加载它,只需将其放在名为role_with_it.rb的文件中,并将其放在lib目录中。

我想用锤子拧螺丝吗?

呃,可能;-)

如果我正确读取此信息,您可能会遇到控制器中的操作具有不同访问级别的情况,因此您希望通过创建单个检查function来删除重复项?

所以你想做这样的事情?

 before_filter :check_role('admin'), :only => [:admin, :debug] before_filter :check_role('power'), :only => [:edit, :delete] 

但是parens中的参数不合法。 无论如何,我仍然在这看到相当多的重复!

一般来说,如果您无法做某事,那么function区域和控制器filter一样,如果您不能做某事,可能是因为您正在以错误的方式查看某些内容。 (请记住,Rails很自豪地将自己描述为“自以为是的软件”!)

如果你能够在过滤方法中知道动作名称,会怎么样?

那我们就有了

 before_filter :check_role 

哪个很干 。

我们可以在Hash中定义权限,也许:

 Perms = { :admin => ['admin'], :edit => ['admin', 'power'], etc 

……似乎封装了重复的不同元素。 如果它变得复杂,那么整个事情可能会转移到一个表中,尽管那时你可能会复制插件中已有的function。

我们有

 protected def check_role for required_role in Perms[params[:action]] return if logged_in_user.has_role? required_role end flash[:notice] = 'Access to that area requires additional privileges.' redirect_to :back end 

或类似的东西。 params [:action]适用于我当前的Rails版本(2.1.2),虽然Rails书(v2)提到了一个似乎为我返回空白的action_name方法。

我不相信你可以将参数传递给filter。 所以我过去做的是制作静态方法,将参数传递给需要参数的方法。

所以我会有这样的事情:

 def check_role(role_name) unless logged_in_user.has_role? role_name flash[:notice] = 'Access to that area requires additional privileges.' redirect_to :back end end def check_admin_role check_role('admin') end def check_blah_role check_role('blah') end 

然后在你的控制器中,你只需要打电话

 before_filter :check_admin_role 

可能有一些方法可以通过元编程实现这一点,但我仍然是一个n00b并且还没有想出那个部分;)

这是一个古老的问题,但是如果有人仍然想知道,可以在这里找到一个好的asnwer for rails 4