【问题标题】:How to manage users and their roles as an admin using acl9如何使用 acl9 以管理员身份管理用户及其角色
【发布时间】:2015-05-23 10:01:02
【问题描述】:

想知道使用 acl9 管理用户角色的最佳方法是什么?

这就是需要:

  • 管理员应该能够更新用户的角色。

以下是问题:

  1. 我们如何列出所有主题角色? :admin, :manager
  2. 为了保持 api 端点 RESTful,我想在 user_controller 的更新方法中传递角色参数。
  3. 我怎样才能只为角色属性授权,以便用户对象的所有者仍然可以修改他们的名字、姓氏字段,但不能修改他们的角色字段?只允许管理员。

我可以在access_control 块之外手动检查参数:

def secure_params
    if current_user.has_role?(:admin)
        params.require(:user).permit(:first_name, :last_name, :role)
    else
        params.require(:user).permit(:first_name, :last_name)
    end
end

但我想我会检查一下是否有更清洁的解决方案。

最后,使用RoleTypes.ADMINRoleTypes.MANAGER 代替:admin 是否可行且明智?如果是这样,最好的方法是什么?该类是否可以在整个 Rails 应用程序中访问?

【问题讨论】:

    标签: ruby-on-rails acl9


    【解决方案1】:

    编辑:完全错过了第一句话中的 acl9 位 - 抱歉!

    话虽如此,我的回答仍然适用;我会有一个辅助方法或使用 acl9 的has_role? 方法并基于此更改视图。即:

    >> <% if @user.has_role?(:foo, nil) %> 
    >>    <p>
    >>    <%= f.label :usertype %><br />
    >>    <%= f.check_box :usertype %>
    >>   </p>
    >> <% end %>
    

    我会使用辅助方法来使用.has_role! 方法实际设置用户角色,即:user.has_role! :som​​e_role, [可选范围],其中 user 是被分配角色的用户。

    有关更多信息,请查看以下内容(来自 acl9 文档): https://github.com/be9/acl9/wiki/Tutorial%3A-securing-a-controller


    好的,所以如果我认为你说的是​​正确的,你想要一种方法让用户可以编辑内容和/或个人资料信息,但管理员可以编辑用户角色。

    首先,我将假设角色是您的用户架构的一部分(如果不是,我建议您考虑将其移到那里)。如果是这样,我建议向您的用户模型 may_edit?(content) 添加一个方法,该方法根据用户角色或 id 返回一个布尔值。即:

    def may_edit?(content) item.user.id == self.id end

    通过控制器中的find_by(id) 找到内容的位置。然后,您可以在控制器中使用if 来指示哪些内容将出现在节目中:

    <% if current_user.role == admin %> <%= some button or link or dropdown render %> <% end %>

    <% if current_user.may_edit?(content) %> <%= some button or link or dropdown render %> <% end %>

    或者类似的东西。您还可以编写 if..else 作为单独的辅助方法或在 may_edit? 方法中(我建议将其作为模型方法)。理想情况下,控制器不应该是决定谁可以和不能执行这种事情的人。如果您打算在控制器中执行此操作,您可能需要查看控制器顶部的:before_filter,即:

    :before_filter admin?, except [:foo, :bar]

    我不确定您要在参数中传递哪个用户 id,但可以找到编辑/管理员或原始发帖人的 id - current_user 将作为 session[:user_id] 和原始用户登录会话海报可以通过正在编辑的内容找到,因为它属于用户并且可以通过 ``User.find_by(content.user_id) 找到。

    最后,您是在问如何查看所有用户角色的列表吗?如果是这样,您可以使用下拉菜单,但您必须在项目中的某个位置对它们进行硬编码,或者遍历每个用户并聚合他们的角色,尽管后者远非理想且效率非常低。

    希望这会有所帮助,祝你好运!

    【讨论】:

    • 对不起,我应该提到我正在使用 acl9 进行授权。这个问题特别是关于我如何让它与那个宝石一起工作。我也在用 ember 客户端构建它,所以在 rails 端我使用的是 rails-api gem。
    • 谢谢亚历克斯。 acl9 生成一个角色表,并为您设置为acts_as_authorization_subject 的任何模型创建连接表。似乎没有一种方法可以使用 acl9 列出所有主题角色。我看到了 roles_for(Object) 但没有看到主题角色。
    【解决方案2】:

    我们如何列出所有主题角色? :admin, :manager

    Role 模型只是一个普通模型,因此您可以像查询其他任何内容一样查询它:

    Role.uniq.pluck :name
    

    为了保持 api 端点 RESTful,我想在 user_controller 的更新方法中传递角色参数。

    一般来说,你最好使用单独的控制器来执行管理,并将其放在Admin:: 命名空间中,并使用namespace :admin do 路由等。

    然后在该控制器中,您可以使用普通的access_control 块来确保没有其他人可以进入:

    class Admin::UsersController < ApplicationController
    
      access_control do
        allow :admin
      end
    
      # ...
    
    end
    

    那么,是的,您可以通过多种方式设置/更新角色,但鉴于用户可以拥有多个角色,最好不要使用单个 :role 参数,而是使用:

    class User < ActiveRecord::Base
      acts_as_authorization_subject
      accepts_nested_attributes_for :roles
    end
    

    那么在您的控制器中,您将拥有:

    def user_params
      params.require(:user).permit(:first_name, :last_name, roles_attributes: [:name])
    end
    

    然后在您的表单中,您可以执行以下操作:

    = form_for :user do |f|
      = f.text_field :first_name
      = f.text_field :last_name
      = f.fields_for :roles do |fr|
        = fr.text_field :name
    

    请注意,我假设您在这里只有简单的角色,而不是对象上的角色,如果您有对象角色,那么您需要一些更复杂的东西来为每个角色捕获 authorizable_idauthorizable_type,并且某种方式来选择要作用的对象。

    我怎样才能只为角色属性授权,以便用户对象的所有者仍然可以修改他们的名字、姓氏字段,但不能修改他们的角色字段?只允许管理员。

    希望您现在已经自己回答了这个问题 - 通过为管理界面和用户自己的界面使用不同的控制器。

    最后,使用 RoleTypes.ADMIN、RoleTypes.MANAGER 代替 :admin 是否可行且明智?

    不,符号更简单更好,尽管这样做很常见:

    class Role < ActiveRecord::Base
      def self.permitted_roles
        %i/admin manager foo bar wee/
      end
    end
    

    这样您就可以使用Role.permitted_roles 来构造复选框数组、下拉列表或类似的东西。

    【讨论】:

    • 非常感谢@smathy,太好了!
    猜你喜欢
    • 2013-09-18
    • 2019-06-02
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2017-05-14
    • 1970-01-01
    • 2013-08-01
    相关资源
    最近更新 更多