我想使用pg_audit_log登录rails应用程序。审核日志不仅必须显示已更改的列,还必须显示进行这些更改的用户。文档没有显示如何执行此操作,但在查看pg_audit_log源(postgresql_adapter.rb)之后,我看到它从线程局部变量中读取用户信息,ala:
current_user = Thread.current[:current_user]
我考虑在过滤器之前和之后设置/取消设置,如下所示:
Thread.current[:current_user] = current_user
(使用控制器中的current_user帮助器方法获取当前登录的用户),但这似乎很危险。我现在花时间试图了解rails请求循环和线程如何交互,以便更好地了解有多危险。与此同时,我很好奇当前使用pg_audit_log的SO用户是否已经解决了每次用户对记录进行更改时将user_id和user_unique_name记录到日志表的需要。
答案 0 :(得分:4)
以您描述的方式设置当前用户是一种常见的方法。例如,请参阅http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
一些示例代码可能如下所示:
# in your model
class User < ActiveRecord::Base
def self.current
Thread.current[:current_user]
end
def self.current=(user)
Thread.current[:current_user] = user if user.nil? || user.is_a?(User)
end
end
# in your controller
class ApplicationController < ActionController::Base
before_filter :set_current_user
def set_current_user
User.current = user_signed_in? ? current_user : nil
end
end
答案 1 :(得分:1)
依靠Thread.current
哈希来提供对控制器管理的对象的模型级访问确实存在争议。例如,请参阅以下内容:
Safety of Thread.current[] usage in rails
令人担忧的是,这个特殊功能在pg_audit_log
gem中没有记录。
假设您没有积极探索gem的源代码,并假设您已经独立决定在您自己的应用程序中定义Thread.current[:current_user] = something
,以用于您自己的目的。在这种情况下,pg_audit_log
会在您不知情的情况下审核该对象。
当然,名称current_user
是如此被普遍接受,意味着当前登录的用户是由身份验证例程定义的,很难将这个潜在的错误想象成一个具体的问题,但从设计的角度来看?哎哟。
另一方面,由于您知道自己在做什么,因此确保在每个响应周期的开始/结束时设置/取消设置Thread.current[:current_user]
应该使过程安全。至少这是我从阅读有关该主题的大量帖子中收集的内容。
干杯,朱塞佩