4

我的控制器中到处都是这个:

if not session[:admin]
  flash[:notice] = "You don't have the rights to do #{:action}."
  redirect_to :action=>:index
  return
end

及其兄弟:

if not session[:user] and not session[:admin]
  flash[:notice] = "You don't have the rights to do #{:action}."
  redirect_to :action=>:index
  return
end

当我想在一个方法中使用它时,我想把它减少到一个声明行:

def action_which_requires_rights
    require_rights :admin
    #or:
    #:require_rights :user_or_admin
end

显然,如果 require_rights 失败,我不希望执行该方法的其余部分。我发誓有办法做到这一点,但我找不到我在哪里读到它。这是我想象的吗?

4

5 回答 5

8

首先你可以这样做:unless session[:admin]而不是if not ...

然后你可以有一个调用你的方法的前置过滤器,这个方法会做你的redirect_to“url”并返回。

我有一个问题,我希望您不只是将管理员的 ID 存储在会话中作为您唯一的身份验证方式,在您的用户模型上拥有一个属性并进行查询,这可能是一个更安全的选择。

于 2009-01-20T00:59:44.663 回答
6

正如其他人所说, before_filter 在这里似乎是正确的工具。但我会解决你所询问的实际模式。

不幸的是,一个方法不能导致它的调用方法返回。与您正在寻找的模式最接近的两个匹配项:

一个块:

def require_rights(rights)
  if session[rights]
    yield
  else
    flash[:notice] = "You don't have the rights to do #{:action}."
    redirect_to :action=>:index
  end
end

所以你会这样做:

def action_which_requires_rights
  require_rights :admin do
    #do whatever here
  end
end

或返回值:

def require_rights(rights)
  return true if session[rights]
  flash[:notice] = "You don't have the rights to do #{:action}."
  redirect_to :action=>:index
  false
end

所以你会这样做:

def action_which_requires_rights
  require_rights :admin or return
  #do whatever here
end

我更喜欢这个块,因为它适合类似的方法,让调用者做or return对我来说有点不自然。

于 2009-01-20T10:08:26.927 回答
3

看看 before_filter。它们可以停止执行,并且可以限制为某些操作。

于 2009-01-20T01:27:37.710 回答
1

如果不允许用户执行此操作,我不会向用户显示操作(我会使用助手来完成此操作)

在控制器中,正如其他答案中提到的,恕我直言,最好的方法是使用过滤器来控制访问权限。

我还建议使用 RESTful 身份验证插件来管理用户角色。

于 2009-01-20T09:08:18.327 回答
0

你可以尝试一些引发异常的东西。

def action_for_admins
  require_rights :admin
end

begin 
  action_for_admins
rescue
  <%= You don't have the rights to do that %>
end

然后 require_rights 应该看起来像这样

def require_rights(*rights)
  rights.each do |right|
    raise "Missing right #{right.to_s}" if not user.has_right?(right)
  end
end

请注意,我是 Ruby 或 Rails 的初学者,所以可能不是这样

于 2009-01-20T09:29:55.367 回答