Почему мои переменные потока периодически появляются в Rails? - PullRequest
1 голос
/ 18 ноября 2010

В моем контроллере приложения есть следующее:

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] выходит как ноль, даже если запросы ранее в запросе работают используя то же значение.

Вопрос в том, почему это не работает, и есть ли лучший способ установить глобальную переменную для текущего запроса?

1 Ответ

6 голосов
/ 18 ноября 2010

Управление локальными переменными 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Само по себе, но в общих чертах это случается не очень часто, и вместо этого обычно возникают конфликты имен методов.

Переменные экземпляра уровня класса сохраняются между запросами в средах, где включен флаг "кеширование классов".В среде разработки ваш класс контроллера перезагружается каждый раз, когда делается запрос, чтобы убедиться, что он отражает текущее состояние ваших исходных файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...