【问题标题】:Filter pages by user按用户过滤页面
【发布时间】:2013-08-07 08:42:20
【问题描述】:

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

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

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

非常感谢您。

【问题讨论】:

  • 我想你可以看看 CanCan gem:github.com/ryanb/cancan
  • 谢谢 Marek,看起来这很适合我的需要。我要试试。最好的问候。

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


【解决方案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 错误。 我们不需要将 owner 与 current_user 进行比较,只需使用 scope access 使权限检查更简单。

一个例子

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

希望这会有所帮助!

【讨论】:

  • 我想问题是关于将某些类型的使用限制为某些操作,而不是按 current_user 过滤记录。
  • Marek 在 cmets 中说得很好,CanCan gem 会做得很完美。
  • 对我来说,将事物范围限定为当前用户是添加 pundit 或 cancan 以根据用户标志、月亮周期等进行细粒度访问控制之前的步骤。
  • 它只会按current_user用户过滤记录,在索引页面你会看到属于你的记录,动作显示、编辑、新建、更新、创建和销毁将仅适用于特定记录如果它属于 current_user。这是一件好事,但与通过类型限制用户访问没有任何共同之处。
  • 我不太确定这是否是您要求的... 1. 医生有很多病人; 2、患者报告多; 3.患者属于医生; 4. 报告属于患者。管理员走他的路;)
猜你喜欢
  • 2015-03-13
  • 1970-01-01
  • 2019-12-06
  • 2021-12-29
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
相关资源
最近更新 更多