按用户过滤页面

时间:2013-08-07 08:42:20

标签: ruby-on-rails ruby ruby-1.9.3

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

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

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

非常感谢你。

1 个答案:

答案 0 :(得分:1)

当您的用户通过以下方式进行身份验证时设计或清除,登录用户可通过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 Best Practices的示例:

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

希望这有帮助!