ruby-on-rails - 如何在我的 ConnectionAdapter 回调中使用设计方法?
问题描述
我有一个 Rails 5.1 应用程序,它使用 Devise 处理我的User
模型的身份验证。这个应用程序有一个 Oracle 数据库后端,需要在执行任何查询之前使用登录用户设置系统上下文变量,所以我希望在:checkout
ConnectionAdapter 的回调中执行此操作。
class ApplicationController < ActionController::Base
before_action :log_user
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.set_callback :checkout, :after do
# Would like to get the logged-in user's username here so I can apply
# it to the oracle sys_context.
# The below throws "undefined method 'user_signed_in?'"
username = current_user.username if user_signed_in?
end
def log_user
# When in this method, user_signed_in? and current_user work fine.
puts "User is #{current_user.username}" if user_signed_in?
end
end
user_signed_in?
在回调块中运行时找不到该方法:checkout
,尽管它通常在控制器中可用。为什么?
此外,current_user
在块内似乎评估为current_user
ConnectionAdapter 中定义的方法,而不是 Devise 定义的方法。我怎样才能访问 Devise 的current_user
?
如何在此回调中使用这些 Devise 提供的方法?
解决方案
您不能使用checkout
回调,在它执行时,它与控制器上下文没有连接。您在此处定义它的事实ApplicationController
与它实际执行的上下文无关。
您将需要before_action
在控制器上下文中设置连接选项。就像是:
before_action :set_user_context
def set_user_context
if current_user
ApplicationRecord.connection.execute "DBMS_SESSION.SET_CONTEXT('whatever', 'goes', 'here', '#{current_user.username}')"
end
end
...或类似的东西。请注意,您可能希望添加一个checkin
回调以在连接完成时清除该值。
顺便说一句,几天前我回答了一个几乎相同的问题:https : //stackoverflow.com/a/54837596/152786 虽然不同的命令,但可能会有所帮助。
推荐阅读
- python - 如果在一组字符之前有内容,则匹配一行,在行的开头
- javascript - 当屏幕尺寸发生变化时如何获得图像宽度?
- css - 无法设置我的反应项目,使其宽度和高度是内容的完整大小
- database-design - 规范化导致查询过多?
- php - preg_match_all 的问题:编译失败的括号不匹配
- apache-kafka - 即使在使用 app.spring.cloud.stream.bindings.output.producer.headerMode=raw 之后,也会在 Kafka 0.10 中记录 contentType
- python - 如何在python中使用来自bash的数据流和子进程
- python - 递归神经网络二元分类
- xpath - 试图找到所有没有带有 & 的“修饰符”子节点的节点
- docker - Docker - 从本地网络上的其他机器访问