путаница по умолчанию - PullRequest
       25

путаница по умолчанию

1 голос
/ 24 ноября 2011

ОБНОВЛЕНО: Я устанавливаю область действия по умолчанию для некоторых моделей во время выполнения, которое, кажется, работает локально в моей среде разработки, и мой код приведен ниже.

SET_OF_MODELS = [Event, Group, User]
@account = Account.find_by_subdomain(account_subdomain)
SET_OF_MODELS.each { |m| m.set_default_scope(@account.id) }
def set_default_scope(account_id)
 default_scope :conditions=> { :account_id => account_id }
end

Если я выполню этокод в консоли ruby ​​с скажем @ account1, User.first возвращает пользователя @ account1, тогда как если я повторю код с @ account2, то User.first возвращает пользователя @ account1 вместо @ account2.И эта проблема не проявляется при запуске приложения на локальном сервере, но на промежуточном сервере.

Я предполагаю, что к их состояниям, если они действительно кэшируются, но не уверены.Может кто-нибудь объяснить в глубине.

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 02 декабря 2011

Разработка отличается от производства.В рабочем режиме все классы загружаются один раз и кэшируются, поэтому вы не можете переопределять области по умолчанию для каждого запроса.В процессе разработки классы загружаются при каждом запросе, что упрощает разработку: каждое изменение, которое вы делаете в коде, отображается / активируется при следующем запросе.

Если вы действительно хотите, вы можете отключить это поведение в производственной,Это замедлит ваш полный сайт, но, возможно, это не проблема.Чтобы отключить это, вы должны отредактировать config/environments/production.rb, найти строку, содержащую

config.cache_classes = true  

и переключить ее на false.

Надеюсь, это поможет.

1 голос
/ 24 ноября 2011

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

Вы можете использовать around_filter

class ApplicationController < ActionController::Base
  around_filter :set_default_scope
  def set_default_scope
    @account = Account.find_by_subdomain(account_subdomain)
    opts = :condition => {:account_id => @account.id}
    Event.send(:with_scope, opts) do 
      Group.send(:with_scope, opts) do 
        User.send(:with_scope, opts) do
          yield
        end
      end
    end
  end
end

Вы можете рефакторировать .send(:with_scope, opts) в метод класса, такой как with_account_scope(account_id)

0 голосов
/ 14 июня 2012

В приведенном выше коде нет ничего плохого, но проблема была в используемом сервере, т.е. в тонком сервере.Работало отлично после замены тонкого на дворнягу.Я думаю, что thin не разрешал выполнять set_default_scope более одного раза, кроме как после загрузки приложения.

...