授权用户,以便他们只能查看自己的对象

时间:2015-05-25 05:38:58

标签: ruby-on-rails devise authorization

我有一个用户模型,用户有很多病人。用户应该只能查看自己的病人。

实现此目标的最佳方式是什么?

这是我原来的患者表现出的行动。这允许任何登录用户查看任何患者:

 def show
    @patient = Patient.find(params[:id])
    @assessments = @patient.assessments
  end

我可以将它切换到下面,但后来我得到一个错误页面(未找到患者ID),我不确定这是否是处理它的最佳方式:

 def show
    @patient = current_user.patients.find(params[:id])
    @assessments = @patient.assessments
  end

处理这样的简单授权的最佳方法是什么?没什么好看的,只是希望用户只能查看和编辑他们自己的东西。

修改

以下是我在尝试访问其他用户的病人时遇到的错误:

Couldn't find Patient with 'id'=27 [WHERE "patients"."user_id" = ?]

相反,我更愿意向用户显示一条消息,说明他们未获得授权。

2 个答案:

答案 0 :(得分:0)

def show

 @patient = Patient.where(id: params[:id],user_id: current_user.id)
 @assessments = @patient.assessments

这里@pateint将为当前登录用户和所有患者提供帮助。 @assessments将提供与患者相关的帮助。

答案 1 :(得分:0)

您可以使用 find_by,如果未找到任何内容,它不会抛出错误。

def show
  @patient = Patient.find_by(id: params[:id])
  if @patient && @patient.user == current_user
    @assessments = @patient.assessments
  elsif @patient.user != current_user
    flash.now[:danger] = 'You are not authorized!'
  else
    flash.now[:danger] = 'The patient was not found'
  end
end

那么你应该在你的视图中测试病人是否存在。

然而,这看起来有点混乱和重复,所以你可以重构,例如通过创建一个新函数。将其放入模型 patient.rb 中,如果 current_user 来自 application_helper,您可能必须include ApplicationHelper

authorized?
  self.id == current_user.id
end

现在第一个代码示例的条件可能是这样的:

if @patient
  @assessments = @patient.assessments 
  unless @patient.authorized?
    flash[:danger] = 'You are not authorized!'
    # here, redirect the user away from the show page
  end
else
  flash.now[:danger] = 'The patient was not found'
end