嗨,我是一名新手程序员,可能我的问题很愚蠢,但我正在网上搜索(以及在此站点上),但找不到答案(可能我没有正确提问)。
问题是我的应用程序中有 3 类用户:患者、医生和管理员,我希望他们每个人(一旦登录)都能看到其中的一些页面。例如,医生只能访问其个人资料和某些患者数据页面,患者只能访问包含其数据的页面,管理员只能访问管理页面。
如何根据用户类型过滤对页面的访问?
非常感谢您提前。
嗨,我是一名新手程序员,可能我的问题很愚蠢,但我正在网上搜索(以及在此站点上),但找不到答案(可能我没有正确提问)。
问题是我的应用程序中有 3 类用户:患者、医生和管理员,我希望他们每个人(一旦登录)都能看到其中的一些页面。例如,医生只能访问其个人资料和某些患者数据页面,患者只能访问包含其数据的页面,管理员只能访问管理页面。
如何根据用户类型过滤对页面的访问?
非常感谢您提前。
当您让您的用户通过 Devise 或 Clearance 等身份验证时,登录用户可通过该current_user
方法获得。只需将您的所有通话范围限定为当前用户。
class PatientsController < ApplicationController
def index
@patients = current_user.patients
end
def show
# Will raise an ActiveRecord::RecordNotFound exception
# if there is not patient with given id or the patient
# is not associated with the current_user
# Renders a 404 error in production
@patient = current_user.patients.find(params[:id])
end
end
Rails 最佳实践的一个例子:
class PostsController < ApplicationController
def edit
# raise RecordNotFound exception (404 error) if not found
@post = current_user.posts.find(params[:id])
end
end
所以我们只在 current_user.posts 中找到可以保证该帖子为 current_user 拥有的帖子,否则将引发 404 错误。我们不需要将所有者与 current_user 进行比较,只需使用范围访问来简化权限检查即可。
class User < AR::B
has_many :patients
has_many :reports, through: :patients
end
class Patient < AR::B
belongs_to :user
has_many :reports
end
class Report < AR::B
belongs_to :patient
end
# config/routes.rb
resources :patients
class PatientsController < ApplicationController
# Ensure that a user is signed in (via Devise)
before_action :authenticate_user! # before_filter in Rails 3
# Load the patient before certain actions
before_action :load_patient, only: [:show, :edit, :update, :destroy]
def index
# Scoping to the current_user ensures that a doctor can only see his patients
@patients = current_user.patients
end
def show
end
def new
@patient = current_user.patients.build
end
def create
@patient = current_user.patients.build(patient_params)
if @patient.save
redirect_to @patient, notice: 'Patient has been created.'
else
render :new
end
end
def edit
end
def update
if @patient.save
redirect_to @patient, notice: 'Patient has been updated.'
else
render :edit
end
end
def destroy
@patient.destroy
redirect_to patients_path, notice: 'Patient has been destroyed.'
end
private
def load_patient
@patient = current_user.patients.find(params[:id])
end
def patient_params
params.require(:patient).permit(:first_name, :last_name)
end
end
范围界定使用户能够仅编辑他们自己的记录以及与他们关联的记录。
当您需要更细粒度的访问逻辑时(例如,只有当医生想要接收消息时,患者才能向医生发送消息),我建议您查看Pundit。
希望这可以帮助!