ActiveSupport::CurrentAttributes provides a thread-isolated attributes singleton

简介: ActiveSupport::CurrentAttributes provides a thread-isolated attributes singleton

使用场景:需要 persist 一些全局数据,如 request 中内容,user 之类

Abstract super class that provides a thread-isolated attributes singleton.

Primary use case is keeping all the per-request attributes easily available to the whole system.

The following full app-like example demonstrates how to use a Current class to facilitate easy access to the global, per-request attributes without passing them deeply around everywhere:

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :account, :user
  attribute :request_id, :user_agent, :ip_address 
  resets { Time.zone = nil }
  def user=(user)
    super
    self.account = user.account
    Time.zone = user.time_zone
  end
end
# app/controllers/concerns/authentication.rb
module Authentication
  extend ActiveSupport::Concern
  included do
    before_action :set_current_authenticated_user
  end
  private
    def set_current_authenticated_user
      Current.user = User.find(cookies.signed[:user_id])
    end
end
# app/controllers/concerns/set_current_request_details.rb
module SetCurrentRequestDetails
  extend ActiveSupport::Concern
  included do
    before_action do
      Current.request_id = request.uuid
      Current.user_agent = request.user_agent
      Current.ip_address = request.ip
    end
  end
end  
class ApplicationController < ActionController::Base
  include Authentication
  include SetCurrentRequestDetails
end
class MessagesController < ApplicationController
  def create
    Current.account.messages.create(message_params)
  end
end
class Message < ApplicationRecord
  belongs_to :creator, default: -> { Current.user }
  after_create { |message| Event.create(record: message) }
end
class Event < ApplicationRecord
  before_create do
    self.request_id = Current.request_id
    self.user_agent = Current.user_agent
    self.ip_address = Current.ip_address
  end
end

A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result. Current should only be used for a few, top-level globals, like account, user, and request details. The attributes stuck in Current should be used by more or less all actions on all requests. If you start sticking controller-specific attributes in there, you're going to create a mess.

相关文章
|
6月前
|
NoSQL 编译器 API
关于thread使用的错误:pure virtual method called terminate called without an active exception
关于thread使用的错误:pure virtual method called terminate called without an active exception
127 1
|
3月前
类(Class)和实例(Instance)
【8月更文挑战第29天】类(Class)和实例(Instance)。
37 3
|
3月前
Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed while singletons
Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed while singletons
102 3
|
6月前
|
JavaScript
【报错】onMounted is called when there is no active component instance too be associated with.
【报错】onMounted is called when there is no active component instance too be associated with.
414 4
Could not obtain transaction-synchronized Session for current thread原因及解决方案
Could not obtain transaction-synchronized Session for current thread原因及解决方案
282 1
Could not obtain transaction-synchronized Session for current thread原因及解决方案
|
Java Spring
【新手指南】严重: Exception sending context initialized event to listener instance of class
【新手指南】严重: Exception sending context initialized event to listener instance of class
509 0
【新手指南】严重: Exception sending context initialized event to listener instance of class
单方法对象(Single-method Object)
单方法对象(Single-method Object)
104 2
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
|
Java 安全 缓存
final和volatile在thread-safe中的作用
final和volatile都在多线程中有着自己的适用范围,我的简单的理解是:final可以用于常量(初始化之后,引用不被修改),volatile可以用于多个线程的并发读写。
1985 0
|
Java Apache Spring
Exception sending context initialized event to listener instance of class
详细错误信息如下: 严重: Exception sending context initialized event to listener instance of class com.auth.spring.
1223 0