为什么我的线程变量在Rails中是间歇性的?

我的应用程序控制器中有以下内容:

before_filter :set_current_subdomain protected def set_current_subdomain Thread.current[:current_subdomain] = current_subdomain @account = Account.find_by_subdomain(current_subdomain) end def current_subdomain request.subdomain end 

然后我的一些模型中的以下内容:

 default_scope :conditions => { :account_id => (Thread.current[:account].id unless Thread.current[:account].nil?) } 

现在,这有效 – 有些时候。 我例如加载一个索引方法并获取应用了作用域的记录列表,但有时也得到一个空列表,因为Thread.current [:account_id]即将出现为nil,即使请求中较早的查询正在工作使用相同的值。

问题是,为什么这不起作用,是否有更好的方法来设置当前请求的全局变量?

操纵Thread局部变量是一个非常糟糕的主意,除了悲伤,心痛和痛苦之外什么都不会导致。 不能保证请求处理的不同部分将由同一个线程处理,因此,您的变量可能最终会丢失。

Rails约定是在ApplicationController的上下文中创建实例变量。 简单来说,你真正做的就是:

 class ApplicationController < ActionController::Base before_filter :set_current_subdomain attr_reader :current_subdomain helper_method :current_subdomain protected def set_current_subdomain @current_subdomain = request.subdomain @account = Account.find_by_subdomain(@current_subdomain) end end 

您创建的任何@...类型变量将附加到与当前请求关联的ApplicationController实例。 重要的是要注意每个请求将被发布一个适当的控制器类的全新实例。

你可以自由地创建你想要的任何实例变量,只要它们不会与Rails本身使用的那些冲突,但一般而言,这种情况不会经常发生,而且通常会在方法名称上发生冲突。

在启用“缓存类”标志的环境中,类级实例变量将在请求之间保持不变。 在开发环境中,每次发出请求时都会重新加载控制器类,以确保它反映源文件的当前状态。