The use case I recently had was that a
Cache-Control header was being sent in
by the requester, and I needed the value of that header really quite deeply
into the application. I needed to store a variable throughout the
request-response life cycle.
There’s a Rails solution in CurrentAttributes.
# app/models/response_headers.rb class ResponseHeaders < ActiveSupport::CurrentAttributes attribute :cache_control end # app/controllers/home_controller.rb class HomeController < ApplicationController before_action :set_cache_headers def index end private def set_cache_headers ResponseHeaders.cache_control = request.headers.fetch('Cache-Control', '') end end # app/lib/something_else.rb class SomethingElse def cache_headers? ResponseHeaders.cache_control.blank? end end
My initial implementation just used
directly and storing a singleton there.
As far as I know, CurrentAttributes is just sugar around that, and when you have a library already inside your codebase doing the thing you want to do, just lean on that to hide away complexity. CurrentAttributes leads to a fairly clean looking object and only a little documentation to understand what’s going on.
It has all the problems that come with threads though: if you spin up a thread to do some other piece of work, it won’t have access to the CurrentAttribute’d object. (Or it will, but it will be a new instance.)
It’s not all that typical to use threads (in my experience), so you may not think you’re using any but double check your other libraries. Many HTTP client libraries will use threads to parellelise requests.