如何将参数发送到之前的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