如何在API认证后调用PaperTrail的info_for_paper_trail方法
解决PaperTrail在API认证后设置whodunnit的问题
背景
我的API控制器继承自ActionController::API,通过组织密钥进行API认证,认证代码如下:
api_key = request.headers["HTTP_AUTHORIZATION_TOKEN"] @organization = Organization.find_by(api_key: api_key)
需要用@organization设置PaperTrail的whodunnit和whodunnit_type,且组织存在多种类型。
核心问题
如何在认证完成后调用PaperTrail的info_for_paper_trail方法?
当前问题
info_for_paper_trail方法在认证前就被调用,此时@organization尚未赋值。
已尝试方案
- 在控制器中认证后使用
before_action过滤器调用:info_for_paper_trail被调用两次,一次是PaperTrail默认调用(此时无@organization),一次是手动调用(已设置whodunnit和whodunnit_type,但未写入版本表)。
- 在认证方法内直接调用
info_for_paper_trail:- 同样能设置
whodunnit和whodunnit_type,但数据不会保存到版本表。
- 同样能设置
正确解决方案
方式一:重写info_for_paper_trail并确保认证优先执行
不需要手动调用info_for_paper_trail,而是重写该方法,让它直接从控制器的@organization取值,同时保证认证逻辑在PaperTrail的回调之前运行:
class ApiController < ActionController::API # 先执行认证,再加载PaperTrail的控制器助手 before_action :authenticate_organization! include PaperTrail::ControllerHelpers private def authenticate_organization! api_key = request.headers["HTTP_AUTHORIZATION_TOKEN"] @organization = Organization.find_by(api_key: api_key) # 可选:添加认证失败处理 # head :unauthorized unless @organization end def info_for_paper_trail { whodunnit: @organization&.id, whodunnit_type: @organization&.class.name } end end
PaperTrail在生成版本记录时会自动调用重写后的info_for_paper_trail,此时@organization已经通过认证方法完成赋值,能正确获取所需数据。
方式二:手动设置PaperTrail请求上下文
如果重写方法不符合需求,可在认证完成后直接绑定PaperTrail的请求上下文,后续生成版本时会自动使用这些值:
class ApiController < ActionController::API include PaperTrail::ControllerHelpers before_action :authenticate_organization! private def authenticate_organization! api_key = request.headers["HTTP_AUTHORIZATION_TOKEN"] @organization = Organization.find_by(api_key: api_key) if @organization PaperTrail.request.whodunnit = @organization.id PaperTrail.request.whodunnit_type = @organization.class.name end end end
内容的提问来源于stack exchange,提问作者Mr.Muhammad Ramzan
相关产品推荐
相关产品推荐

