编辑@HarsHarl 的答案可能更有意义,因为这个答案非常相似。
使用Thread.current[:current_user] 方法,您必须进行此调用才能为每个请求设置User。您说过您不喜欢为每个很少使用的请求设置一个变量的想法;您可以选择使用skip_before_filter 来跳过设置用户,或者不将before_filter 放在ApplicationController 中,而是将其设置在您需要current_user 的控制器中。
模块化方法是将created_by_id 和updated_by_id 的设置移动到关注点,并将其包含在您需要使用的模型中。
可审计模块:
# app/models/concerns/auditable.rb
module Auditable
extend ActiveSupport::Concern
included do
# Assigns created_by_id and updated_by_id upon included Class initialization
after_initialize :add_created_by_and_updated_by
# Updates updated_by_id for the current instance
after_save :update_updated_by
end
private
def add_created_by_and_updated_by
self.created_by_id ||= User.current.id if User.current
self.updated_by_id ||= User.current.id if User.current
end
# Updates current instance's updated_by_id if current_user is not nil and is not destroyed.
def update_updated_by
self.updated_by_id = User.current.id if User.current and not destroyed?
end
end
用户模型:
#app/models/user.rb
class User < ActiveRecord::Base
...
def self.current=(user)
Thread.current[:current_user] = user
end
def self.current
Thread.current[:current_user]
end
...
end
应用程序控制器:
#app/controllers/application_controller
class ApplicationController < ActionController::Base
...
before_filter :authenticate_user!, :set_current_user
private
def set_current_user
User.current = current_user
end
end
示例用法:在其中一个模型中包含 auditable 模块:
# app/models/foo.rb
class Foo < ActiveRecord::Base
include Auditable
...
end
在Foo 模型中包含Auditable 关注点将在初始化时将created_by_id 和updated_by_id 分配给Foo 的实例,因此您可以在初始化后立即使用这些属性,并将它们持久化到@987654340 @table 上的 after_save 回调。