Rails 如何在 observer 生成 log 时取得"当前登陆用户"的信息?

ruohanc · 2012年05月11日 · 最后由 ery 回复于 2013年08月26日 · 4618 次阅读

标题已经不知道怎么写了,我想要的是进行一个动作后,记录下 log. 并且同时记录下是谁进行了这个动作 ( 使用 devise 认证 )

遇到的问题是在 model 里面不能调用 current_user, 所以无法记录下是谁进行的操作。按照我的想法。这种功能应该是实现在 observer 里面的,但是在 observer 中如何才能确定现在登陆的用户呢..?

用代码来说下这个问题是这样的:

class ProjectObserver < ActiveRecord::Observer
def after_save(proj)
    Event.create(
      :project => self,
      :type => xxx,
      :author =>  current_user  #怎么获得这个用户, devise 的 current_user helper 用不了 
    )
  end
end

如果有另外的方法解决这个问题也行...我是觉得这个逻辑不应该放进 controller 里 ( controller 里面可以用 current_user) , 所以把自己卡住了。

以前一直在 controller 层操作

proj 要有当前用户才行,类似 model 层的操作~

#3 楼 @hooopo 回答的真详尽呀~

@hooopo的方法应该是很优的方法 thread 的方式也许会存在不安全的问题。因为一般的 rails server 的 ruby 进程会一直开着.thread 的变量需要每次都覆盖或使用后清理掉,不然就有可能拿到的上次或上上次的请求的数据。

#3 楼 @hooopo great! 大赞!用虚拟属性成功绕开了这个问题....

关于前面你说的用 project 的 user_id, 我觉得不太合适..比如这个项目的所有者是 XX.但是他授权 YY 来修改一些项目内容..那这个修改人就不应该写上 XX, 而是被授权的 YY..

#1 楼 @chucai 俺是觉得这逻辑放进 controller 就太不符合分层的精神了.....而且维护起来也麻烦

#2 楼 @mimosa 嗯..用虚拟属性解决了..

#5 楼 @cxh116 嗯...那个诡异的 hack 方法实在是太不放心了...还是虚拟属性好...稳定!

#6 楼 @ruohanc 虚拟属性 的确非常强大。

我觉得 log 可以考虑 用 After Filter 实现

翻出了旧帖子... @hooopo 的方法不错,不过具体到楼主的这个问题,更合理的方式是在 controller 上做事。 这是一个典型的操作日志的需求,而操作日志是来自用户的行为,放在 model 层进行 observe 是有问题的,比如会多记录一些日志(应该是一次操作一条日志,而不是一次模型变更一条日志)

#9 楼 @fsword 我觉的,日志,应该以 Action 为单位,而不是已 Model 操作为单位。 就是说 一个 Action 产生一个日志 而不是 一个 Model 操作 产生一个日志 不过这要求,Action 的设计比较有秩序,可以依赖 restful,进行设计。

#11 楼 @fsword #10 楼 @ery

已经不记得当时为啥要这样写了,大概那时候有个朋友正给我灌输什么 "切面编程" 的概念,然后我就在想怎么实践,最后就变成这样了。

#12 楼 @ruohanc 呵呵,这个例子算不算“手里一把锤子,看哪都像钉子”?

observer 是一个不错的技术, 但是当用户需求依赖 session的时候,observer就不适合了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号