Rails:在请求范围内共享信息

时间:2011-09-06 17:31:15

标签: ruby-on-rails

Rails在当前请求范围内共享信息的机制是什么?

熟悉Asp.Net的人会知道有一个HttpContext可供请求期间调用的所有实体使用。

Rails中有类似内容吗?

2 个答案:

答案 0 :(得分:7)

使用around_filterThread.current[],您可以轻松创建请求上下文/范围。请参阅以下示例。

首先添加application_controller.rb

  around_filter :request_context

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

现在将以下类添加到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

这非常简单。您可以将数据存储在RequestContext.instance对象中,该对象将在每次请求后重新创建。

答案 1 :(得分:1)

据我所知,没有一个内置。在我的书中,对请求范围的哈希的需求是一种难闻的气味。每个请求只有一个关联的操作,从那里你应该使用模型对象来完成大部分工作。

想想Rails MVC“请求”管道:

  1. 浏览器向URI发出请求
  2. Rails根据路由信息查找控制器和操作
  3. Rails创建该控制器的单个实例,并将该操作作为方法调用(任何params []作为参数)
  4. 为响应请求而创建的单个控制器实例仅限于您的当前请求(即;正是您要查找的内容)。如果您需要共享请求数据,请将其放在控制器上或更好,将其置于行动中,甚至更好......在您的模型中。

    你为什么需要这个?