2011-03-18 86 views
5

维护部署在Apache与mod_passenger一个Rails应用程序v2.3.8当前访问用户会话Rails的:在一个模型(

我需要在模型中的一个(审计师观察者获得当前用户会话是精确的) 我知道这违反了MVC的原则,但是我必须违反它,因为我有一个需要知道当前登录用户的观察者,我有很多控制器,并且将呼叫发送给Auditor记录器不会非常干燥。

我只是想能够调用User.current与当前登录的用户会话返回。但我遇到了缓存/线程安全问题。原作者使用类变量(@@当前)来存储当前用户。但这不是线程安全的,所以我把它变成了这个

class User < AR:Base 
    ... 
    def self.current 
    Thread.current[:user] 
    end 

    def self.current=(user) 
    Thread.current[:user] = user 
    end 
    ... 
end 

所以它应该是线程安全的。在审计观察员我有一个电话:

Auditor(subject, action, object) 

我在哪里通过User.current作为主题。

此代码在开发中很有效,但在制作中我从User.current中获取不正确的值。有时我会得到另一个登录用户的记录,而不是当前记录。所以有一些线程安全/类缓存问题仍然存在,但我无法弄清楚如何解决它。

有什么建议吗? 谢谢

回答

3

ActiveRecord和ActionPack是完全不同的,因此您无法访问模型中的会话/ cookie。如果您需要当前用户,您有两种选择。

选项1 - 通过当前用户模型

在你的控制器:

def index 
    Audit.get_current_user(current_user) 
    #where audit is your model that you will send the current_user to 
end 

选项2 - 有一个用户对象被修改后执行动作的用户模型。

在用户模式:

before_save :adjust_user 

def adjust_user 
    #self will be the object that was just modified aka the current user 
end 
+0

这就是为什么我创建了当前的getter/setter方法是线程安全的,但它让我保存/获取当前用户。调用User.current被缓存(我认为)出现问题。 – Swartz 2011-03-19 00:08:13

+0

对于选项1:我可以直接从控制器方法传递current_user,不知道为什么我需要get_current_user()。但我特别希望避免从控制器接到Auditor()的很多电话,因为有很多地方需要这种类型的电话。观察者的工作更干净。 – Swartz 2011-03-19 00:11:27

+0

对于选项2:我没有关注你...用户对象不是唯一被修改的东西。我有各种对象,登录用户可以修改(如政策,权限等)。将审计员视为活动记录器。用户可以CRUD策略,权限等,所以我仍然必须将current_user传递给Auditor模型。 – Swartz 2011-03-19 00:15:11

相关问题