2

嗨,我是一名新手程序员,可能我的问题很愚蠢,但我正在网上搜索(以及在此站点上),但找不到答案(可能我没有正确提问)。

问题是我的应用程序中有 3 类用户:患者、医生和管理员,我希望他们每个人(一旦登录)都能看到其中的一些页面。例如,医生只能访问其个人资料和某些患者数据页面,患者只能访问包含其数据的页面,管理员只能访问管理页面。

如何根据用户类型过滤对页面的访问?

非常感谢您提前。

4

1 回答 1

1

当您让您的用户通过 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

希望这可以帮助!

于 2013-08-07T08:54:58.013 回答