ruby-on-rails - 当 ActiveRecord::RecordNotFound 未检测到用户等于 nil 时如何处理
问题描述
我只是在学习编程,尤其是 Ruby on Rails。我目前面临的问题是,我怀疑在干净的代码和避免我的代码异味或其他可能的问题方面,以哪种方式处理我的问题更好。
所以基本上,我有 users_controller 来检查我jwt
的是否有效:我对其进行解码,撤回user_id
并在 DB 中查找用户id
。
def login
user = decoded_user(permitted_params[:jwt])
render json: user
rescue ActiveRecord::RecordNotFound, JWT::DecodeError
render status: 401, json: { error: 'invalid token' }.to_json
end
如您所见,如果 jwt 无效或未找到用户,它必须呈现401 error
,但不知何故,当用户存在时nil
,rescue ActiveRecord::RecordNotFound
不会检测到它并200 status
在我想要它时呈现401
。当jwt
有效或为空时,一切正常。
我想把它包装成if else
块,以防万一nil
对我来说它似乎不是很熟练。你能帮我重构一下吗?谢谢!
解决方案
有两种不同的方法可以通过最小的更改来处理这个问题。
找比!
首先是确保在找不到用户时引发异常。您已经使用find_by
,文档中说:
如果没有找到记录,则返回
nil
。
对于 Rails 中的许多查找器方法,都有以 a!
结尾的变体。指示在 Rails 上下文中该!
方法将引发异常。对于find_by
,存在相同的find_by!
变体。此方法的文档告诉您,它与 完全一样find_by
,只是它不会返回nil
,而是引发异常。
替换find_by
为decode_user
,find_by!
您的方法应该按预期工作。
避免异常
引发异常通常被视为一种反模式。这有很多不同的原因,但经常使用的一个论点是异常缓慢。如果您查看 Rails 在使用脚手架时生成的代码,您会发现控制器操作通常如下所示:
def create
@test = Test.new(test_params)
if @test.save
redirect_to @test, notice: 'Test was successfully created.'
else
render :new
end
end
您也可以为您的方法使用相同的模式。首先,解码用户。然后检查用户是否存在,例如使用user.present?
. 基于此,要么返回成功,要么返回失败。
您会在 Rails 中看到很多这种模式,我建议您在此处重构代码以遵循它...
推荐阅读
- dataset - 通过 http 将 AWS Common Crawl 的小样本下载到本地机器
- decode - 如何打开 cpp 文件并给出此消息“文件未显示在编辑器中,因为它是二进制文件或使用了不受支持的文本编码”?
- typescript - 如何检查打字稿的repl(ts-node)中的类型?
- python - 评估我的 CNN 停止并显示消息“OOM 分配具有形状 [3,3,256,512] 的张量时”
- routes - 控制器中的子路由
- asp.net-core - .Net Core AspNetCoreHostingModel 是什么意思?
- javascript - 对字符串和数字使用汇总
- r - 如何通过应用特定函数来聚合 data.table 中的重复行
- python - 如何使用 python 套接字连接不同网络上的 2 台计算机
- api - 如何处理 Visa Cybersource Payments API 中扣除服务费的付款?