使用Rolify定义角色

Mel*_*Mel 6 roles ruby-on-rails user-roles rolify

我正在尝试用Rails 4创建一个应用程序.

我正在寻找角色管理,并希望使用Rolify,因为它支持实例级角色分配.

对于其他看同一个问题的人来说,下面有2个非常好的答案(我只能打一个,但我用了两个).查看下面的lorefnon和Cyb3rDud3答案).我还在搞清楚,但是已经使用数组(如lorefnon节目)和控制器/路由功能(如Cyb3rDud3所示)进行了迁移.

令我感到困惑的是,Rolify gem的所有文档都使用控制台来定义角色.

如何在代码中定义角色?

该板上的其他人提出了一些问题,这些问题暗示他们在db:seeds文件中定义了角色.我不想这样做,因为我想控制谁使用我的种子文件比谁可以创建角色更紧密.

你在哪里做的?

所有示例都显示它是从控制台完成的.我想定义角色的列表,然后我想给角色的权限(我想用评论员对于这部分).

我有一个用户模型.我看到的另一个宝石是角色模型.它要求您在用户模型中创建角色数组.它很明显你应该在Rolify中做到这一点 - 没有一个文件能给你这一步吗?

你在哪里定义角色?

lor*_*non 8

令我感到困惑的是,Rolify gem的所有文档都使用控制台来定义角色.

Rolify文档不使用控制台来定义角色 - 它演示了如何在纯ruby中添加角色.这非常强大,因为您可以在运行ruby时定义角色.您不限于某些配置文件或某些数据库表中定义的静态角色列表.


您需要问的第一个问题是何时创建角色?

最常见的用例分为两组:

1.角色是静态的.

应用程序安装/部署期间应用程序开发人员,支持人员或公司高管创建一次角色,并且在正在运行的应用程序的生命周期中,这些预先创建的角色将分配给不同的用户.

此类角色的最常见用例包括对公司中人员的建模(开发人员,经理,支持等)进行建模,或对先前已知职责进行建模(编辑,管理员,查看者等)

如果你的角色确实属于这样的用例,那么接下来你必须决定 - 它的职责是创建和修改角色.通常有两种可能性:

1.1.应用程序开发人员本身就是必须添加/删除/修改角色的人.在这种情况下,最好依赖种子数据或Rails迁移.

迁移的优点是,如果需要,您可以轻松地回滚数据.此迁移是rolify生成器生成的迁移的补充,它为您创建角色相关表的模式(请参阅下图).

这样的迁移可能如下所示:

分贝/迁移/ 20151204083556_create_application_roles.rb

class CreateApplicationRoles < ActiveRecord::Migration
  def up
    ['admin', 'support', 'editor'].each do |role_name|
      Role.create! name: role_name
    end
  end
  def down
    Role.where(name: ['admin', 'support', 'editor']).destroy_all
  end

end
Run Code Online (Sandbox Code Playgroud)

有些人正确地认为它是一个反模式,可以通过迁移来管理模式更改和数据更改.data-migrate是一个gem,允许您将以数据为中心的迁移与模式迁移分开.

在这种情况下,实际角色分配的所有其他情况都将基于用户操作或应用程序事件add_roleremove_rolerolify提供的方法发生.这将发生在运行应用程序的生命周期过程中,而不是在应用程序安装期间.

1.2添加/删除/修改角色的任务由支持团队或技术主管完成.在这种情况下,需要提供管理角色的管理界面.

在这种情况下,您将拥有一个rails控制器来管理角色.创建操作将用于创建角色,show action将用于显示角色等.这些操作将具有附带的视图,这些视图将为最终用户提供图形用户界面以管理角色.

2.角色是动态的

此类别涵盖角色被视为更类似于类别或标记并可由最终用户创建/修改/删除的用例.例如,图书馆员可以为特定类型的书籍分配一些角色/类别.

这种情况类似于1.2,因为您必须通过rails控制器处理创建/删除/更新角色.


下一部分是如何在表中构建信息.

Rolify期望一个特定的模式(在某种程度上可自定义),但预期的模式足够灵活,可以处理所有上述用例.

滚动表格


小智 5

我真的只是经历了相同的过程,就像@ user2860931一样,我能找到的是如何从控制台分配角色的一些例子.我需要的是一种以编程方式灵活的方式来管理具有管理角色的用户或具有pmo角色的用户如何将这些角色分配给其他人.

通过一些实验,这就是我为我解决的问题.在这个例子中,我使用Devise进行身份验证,使用Rolify进行角色验证.

我假设您已经安装并运行了Devise,因此您拥有现有的用户模型.按照gem页面上的说明安装Rolify.我使用了角色模型的建议名称Role.所以如此处所述:https://github.com/RolifyCommunity/rolify.安装GEM,使用rolify角色用户生成.并迁移数据库迁移.

这将有效地为您留下一个新的表Roles和与Users表的has_and_belongs_to_many关系.

至于我的目的,我不需要通常的创建读取(显示)更新删除(CRUD)接口的角色,我刚刚通过seeds.rb这样创建了一些.

#Seeding the Role table
#
p "Removing existing #{Role.all.count} roles"
Role.destroy_all
p "Creating 7 roles"
[:user, :admin, :portfolio_manager, :programme_manager,     :project_manager, :coordinator, :pmo].each do |role|
  Role.create( name: role )
end
p "Should have created 7 Roles, roles created: #{Role.all.count}"
Run Code Online (Sandbox Code Playgroud)

我和开发人员一样留下了我的额外评论,所以我一眼就看出它工作得很好.所以当你跑步

rake db:seed

您将设置一些角色.或者,您可以通常的方式创建角色控制器和视图,以允许具有管理角色的用户添加新角色.

现在有趣的一点可以开始了.到目前为止,Devise已经为您的用户做了一切,或者您可能已经完成了自己的控制器,但您需要创建自己的用户控制器和视图.因为我只需要针对每个用户的角色的复选框列表,我已按如下方式完成.这是我的

users_controller.rb

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update]

  def index
    @users = User.all
  end

  def show
  end

  def edit
  end

  def update
    respond_to do |format|
      if @user.update(user_params)
        # TODO: Move hardcode flash message into language file
        format.html { redirect_to @user, notice: 'User was successfully updated.'}
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  private

  def set_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(:username, :email, {role_ids: []})
  end
end
Run Code Online (Sandbox Code Playgroud)

现在你必须为这些路线定义这些路线,使它们不与Devise路线发生冲突.我现在保持简单,并为所有常用途径提供资源,以便强化您的应用程序,您可能希望更改它,并且只允许您实际拥有的路由.

routes.rb

Rails.appliction.routes.draw do
  devise_for :users
  root 'pages#home'
  resources :users    #must be after devise
end
Run Code Online (Sandbox Code Playgroud)

当您现在执行rake路由时,您将获得应用程序的通常路径以使控制器工作.像这样按顺序:

                  Prefix Verb   URI Pattern                      Controller#Action
        new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
           user_password POST   /users/password(.:format)      devise/passwords#create
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                         PATCH  /users/password(.:format)      devise/passwords#update
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
       user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                         PATCH  /users(.:format)               devise/registrations#update
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
             user_unlock POST   /users/unlock(.:format)        devise/unlocks#create
         new_user_unlock GET    /users/unlock/new(.:format)    devise/unlocks#new
                         GET    /users/unlock(.:format)        devise/unlocks#show
                    root GET    /                              pages#home
                   about GET    /about(.:format)               pages#about
                 contact GET    /contact(.:format)             pages#about
                   users GET    /users(.:format)               users#index
                         POST   /users(.:format)               users#create
                new_user GET    /users/new(.:format)           users#new
               edit_user GET    /users/:id/edit(.:format)      users#edit
                    user GET    /users/:id(.:format)           users#show
                         PATCH  /users/:id(.:format)           users#update
                         PUT    /users/:id(.:format)           users#update
                         DELETE /users/:id(.:format)           users#destroy
Run Code Online (Sandbox Code Playgroud)

现在剩下要做的就是构建用户界面,这对我来说是最重要的部分,如果我也正确理解你的话.为了快速构建这个,我的例子并没有很好地呈现完整的css魔法,但我相信你可以按照自己的口味做到这一点.

因此,要显示现有用户并选择列表,请在/ app/views/users文件夹中创建index.html.erb.创建一个简单的show.html.erb和一个编辑,您可以在其中分配和删除现有角色.像这样.

index.html.erb

<!-- TODO: Tidy up this file and make it look good -->
<!-- TODO: Remove hard coded text to a locale file -->
<% @users.each do |user| %>
  <p>
    <%= link_to "#{user.username}<#{user.email}>", user %>
    <%= link_to "edit", edit_user_path(user) %>
  </p>
<% end %>

show.html.erb

<!-- TODO: Tidy up this file and make it look good -->
<!-- TODO: Remove hard coded text to a locale file -->
<p>
  Username: <%= @user.username %>
</p>
<p>
  Email address: <%= @user.email %>  
</p>

<%= link_to "Back", users_path %>

edit.html.erb

<!-- TODO: Tidy up this file and make it look good -->
<!-- TODO: Remove hard coded text to a locale file -->
<p>
 Username: <%= @user.username %>
</p>
<p>
 Email address: <%= @user.email %>
</p>

<%= form_for @user do |f| %>
  <% Role.all.each do |role| %>
    <%= check_box_tag "user[role_ids][]", role.id, @user.role_ids.include?(role.id) %>
    <%= role.name %></br>
  <% end %>
  <%= f.submit %>
<% end %>

<%= link_to "Back", users_path %>
Run Code Online (Sandbox Code Playgroud)

你有它,一个简单的用户界面,列出数据库中的所有可用角色,并提供针对用户记录的勾选框,以启用或禁用此类角色.像这样:

用户记录和角色选择列表的示例

对我来说这对我来说也是一个小问题,但希望这会让你的方式增加逻辑和用户体验.