当您让您的用户通过例如身份验证时设计或清除,登录用户可通过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。
希望这会有所帮助!