Ruby on Rails 6中Active Admin+Devise三用户角色实现方案问询
嘿,作为Rails新手,我非常推荐你用单User模型+角色字段的方案来实现多角色流程,比多模型的方式更易维护、也更顺畅。下面是一步步的详细操作,跟着来就好:
一、安装基础依赖
首先确保你的Rails 6项目已经创建,然后依次安装Devise和Active Admin:
- 安装Devise:在Gemfile里添加
gem 'devise',然后运行bundle install,接着执行rails generate devise:install完成初始化。 - 安装Active Admin:Gemfile添加
gem 'activeadmin',运行bundle install,然后执行rails generate active_admin:install,最后rails db:migrate完成数据库迁移。
二、创建带角色字段的User模型
我们用Devise生成User模型,同时添加role字段来区分三种角色:
- 执行命令:
rails generate devise User role:string - 打开生成的迁移文件(位于
db/migrate/目录下),给role字段加默认值(新手推荐加上,避免空值问题),修改后的迁移内容大概是:
class DeviseCreateUsers < ActiveRecord::Migration[6.1] def change create_table :users do |t| # Devise默认字段(邮箱、密码等) t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" # 新增角色字段,默认是普通用户 t.string :role, default: "user" # 其他Devise自带字段(可根据需求保留/删除) t.string :reset_password_token t.datetime :reset_password_sent_at t.datetime :remember_created_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true end end
- 执行
rails db:migrate应用迁移。 - 打开
app/models/user.rb,用Rails的enum来管理角色(这能让角色判断更简洁直观):
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable # 定义三种角色,默认是普通user enum role: { user: "user", moderator: "moderator", administrator: "administrator" }, default: "user" end
三、配置Devise的角色权限控制
我们需要在全局控制器里添加角色判断的方法,方便后续调用:
打开app/controllers/application_controller.rb,添加以下内容:
class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :configure_permitted_parameters, if: :devise_controller? protected # 允许注册/更新时提交role字段(后续只有管理员能手动修改普通用户的角色) def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:role]) devise_parameter_sanitizer.permit(:account_update, keys: [:role]) end # 判断当前用户是否是管理员 def administrator? current_user&.administrator? end # 判断当前用户是否是版主或管理员(有权访问后台) def authorized_user? current_user&.administrator? || current_user&.moderator? end # 权限拦截:只有授权用户(版主/管理员)能访问后台 def authenticate_authorized_user! unless authorized_user? flash[:alert] = "你没有权限访问此页面" redirect_to root_path end end end
四、集成Active Admin并设置角色权限
接下来配置Active Admin,让不同角色拥有不同的后台操作权限:
- 修改Active Admin的初始化文件
config/initializers/active_admin.rb,找到authenticate_with的配置,替换成我们自定义的权限验证:
config.authenticate_with do authenticate_authorized_user! end # 设置当前用户为Devise的current_user config.current_user_method = :current_user
- 生成Active Admin的User资源(这样我们可以在后台管理用户):
执行命令:rails generate active_admin:resource User - 打开生成的
app/admin/user.rb,配置不同角色的操作权限:
ActiveAdmin.register User do # 只有管理员能看到用户管理菜单 menu if: proc { current_user.administrator? } # 自定义列表显示字段 index do selectable_column id_column column :email column :role column :created_at actions end # 自定义表单字段:限制版主不能设置管理员角色 form do |f| f.inputs "用户信息" do f.input :email f.input :password f.input :password_confirmation # 管理员可以设置所有角色,版主只能设置普通用户和版主 role_options = current_user.administrator? ? User.roles.keys : User.roles.keys.reject { |r| r == "administrator" } f.input :role, as: :select, collection: role_options end f.actions end # 控制器层权限拦截:版主不能修改/删除管理员账户 controller do def update if !current_user.administrator? && resource.administrator? flash[:alert] = "你不能修改管理员账户" redirect_to admin_users_path else super end end def destroy if !current_user.administrator? && resource.administrator? flash[:alert] = "你不能删除管理员账户" redirect_to admin_users_path else super end end end end
五、测试完整流程
现在启动服务器rails s,测试以下场景:
- 普通用户流程:注册新用户,默认角色是
user,登录后看不到Active Admin入口,直接访问/admin会被拦截到首页。 - 版主流程:先在rails控制台创建管理员账户:
User.create(email: "admin@example.com", password: "123456", role: "administrator"),用管理员登录后台创建一个moderator角色的用户。用版主账号登录后,能进入后台,但看不到管理员用户,也不能设置管理员角色。 - 管理员流程:管理员登录后,能管理所有用户,包括创建、编辑、删除任何角色的账户。
这样一套流程下来,既实现了三种角色的权限隔离,又比多模型方案更简洁易维护,非常适合新手入门。
内容的提问来源于stack exchange,提问作者user7435957




