Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: share information within a Request scope

What's the mechanism in Rails to share information within the current request scope?

Those familiar with Asp.Net would know there is a HttpContext that is available to all the entities that are invoked during a request.

Anything similar in Rails?

like image 716
thanikkal Avatar asked Sep 06 '11 17:09

thanikkal


1 Answers

With around_filter and Thread.current[] you can easily create a request context/scope. See the following example.

First add in your application_controller.rb:

  around_filter :request_context

  def request_context
    begin
      RequestContext.begin_request
      yield
    ensure
      RequestContext.end_request
    end
  end

now add the following class to lib/request_context.rb

class RequestContext
  def self.instance
    i = Thread.current[:request_context]
    unless i
      raise "No instance present. In script/rakefiles: use RequestContext.with_scope {}, " +
            "in controller: ensure `around_filter :request_scope` is configured"
    end
    return i
  end

  # Allows the use of this scope from rake/scripts
  # ContextScope.with_scope do |scope|
  #   # do something
  #   ...
  # end
  def self.with_scope
    begin
      begin_request
      yield(instance)
    ensure
      end_request
    end
  end

  def self.begin_request
    raise "request_context already set" if Thread.current[:request_context]
    Thread.current[:request_context] = RequestContext.new
  end

  def self.end_request
    raise "request_context already nil" unless Thread.current[:request_context]
    Thread.current[:request_context] = nil
  end

  # user part, add constructors/getters/setters here

  def initialize
    # you can setup stuff here, be aware that this
    # is being called in _every_ request.
  end
end

This is pretty straightforward. You can store data in the RequestContext.instance object, the object will get recreated after every request.

like image 97
reto Avatar answered Sep 28 '22 01:09

reto