我一直在努力为我的组织开发人力资源管理系统,并创建了基础设施。我现在已经到了需要创建管理员授权的程度。我的组织非常基于树状结构,而且从我所掌握的内容来看,我想要做的事情在某些管理宝石(如主动管理员)中并没有得到真正的帮助(尽管如果我能帮助我,请纠正我。我错了!)。我考虑在下面的每个级别使用parent_id
字段,但我不确定如何在应用中为此提供便利。
实际上,我希望最低级别的员工能够查看他们的大部分个人数据减去一些类别,例如绩效报告/备注和类似属性,并且能够编辑基本详细信息,例如联系人详细信息。确保它们是最新的。然后,他们的直线经理应该能够查看他们负责的员工的所有细节。该组织大约有四层,但我想保持它的可扩展性。在第二层和第三层也有多个线路经理,我认为这是宝石出现问题的地方。
我已经安装了Ancestry gem,因为我认为这将是揭开困境的关键,但想知道是否有人有任何好主意。我当前的employee.rb
文件位于下方,只是不确定从何处开始。
class EmployeesController < ApplicationController
before_action :set_employee, only: [:show, :edit, :update, :destroy]
before_action :logged_in_employee, only: [:index, :show, :edit, :update, :destroy]
before_action :correct_employee, only: [:show, :edit, :update]
before_action :admin_employee, only: :destroy
# GET /employees
# GET /employees.json
def index
@employees = Employee.paginate(page: params[:page])
end
# GET /employees/1
# GET /employees/1.json
def show
end
# GET /employees/new
def new
@s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: 201, acl: :public_read)
@employee = Employee.new
end
# GET /employees/1/edit
def edit
@employee = Employee.find(params[:id])
end
# POST /employees
# POST /employees.json
def create
@employee = Employee.new(employee_params)
if @employee.save
@employee.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
# PATCH/PUT /employees/1
# PATCH/PUT /employees/1.json
def update
respond_to do |format|
if @employee.update(employee_params)
flash[:success] = "Profile updated"
format.html { redirect_to @employee, notice: 'Employee was successfully updated.' }
format.json { render :show, status: :ok, location: @employee }
else
format.html { render :edit }
format.json { render json: @employee.errors, status: :unprocessable_entity }
end
end
end
# DELETE /employees/1
# DELETE /employees/1.json
def destroy
Employee.find(params[:id]).destroy
flash[:success] = "Employee deleted"
respond_to do |format|
format.html { redirect_to employees_url, notice: 'Employee was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_employee
@employee = Employee.find(params[:id])
end
# Confirms a logged-in user.
def logged_in_employee
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_employee
@employee = Employee.find(params[:id])
redirect_to(root_url) unless current_employee?(@employee)
end
# Confirms an admin user.
def admin_employee
redirect_to(root_url) unless current_employee.admin?
end
# Never trust parameters from the scary internet, only allow the white list through.
def employee_params
params.require(:employee).permit(:avatar, :email, :first_name, :last_name, :service_no, :password, :date_of_birth, :gender, :service_start_date, :substantive_rank, :promotion_date, :passport_number, :passport_expiry, :passport_country_of_origin, :nationality, :national_insurance)
end
end
答案 0 :(得分:0)
在ActiveAdmin中,授权发生在access a resource(或collection)。它基本上使用操作名称(例如index
,show
,edit
,update
等)以及模型对象或类,具体取决于可用于授权请求的内容。如果没有配置,ActiveAdmin不提供授权解决方案。如果你没有配置任何东西,它将让任何用户做任何事情。
ActiveAdmin的授权方法与cancan gem(或者更确切地说是其继承者cancancan gem)的效果非常好,但Pundit也支持开箱即用。滚动你自己的适配器也很容易:你可以轻松地使用任何宝石。
针对您的具体问题:
员工之间的关系以及您如何进行授权并不一定必须相互影响。基于角色的方法似乎很好地解决了您的问题。例如,您可以为不同的层次结构级别创建角色:
用户可以拥有多个角色或角色可以包含在内(直线经理可以执行员工可以执行的所有操作)。据我所知,后者更适合你的问题。
对于有人想要更新用户的联系信息(不一定是她自己的)的具体情况,您必须检查用户的角色是否允许更新操作以及当前用户是否有权访问另一个用户对象。如果是员工,则必须是自己,但是直线经理可以更新她的下属&#39;联系信息。
大多数授权库提供了一种表达不同角色可以执行的操作的声明方式。我鼓励你去看看cancancan宝石。