默认范围混乱

时间:2011-11-24 10:20:46

标签: ruby-on-rails activerecord ruby-on-rails-2

更新: 我在运行时设置某些模型的默认范围,这似乎在我的开发环境中本地工作,我的代码如下所示。

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

如果我使用@ account1在ruby控制台中执行此代码,User.first将返回@ account1用户,而如果我使用@ account2重复代码,则User.first将返回@ account1用户而不是@ account2。在本地服务器中运行应用程序但在登台服务器中没有显示此问题。

如果他们真的被缓存但不确定,我的猜测是针对他们的州。有人可以深入解释。

提前致谢

3 个答案:

答案 0 :(得分:1)

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)

的类方法

答案 1 :(得分:1)

发展与生产不同。在生产中,所有类都加载一次并缓存,因此您无法在每个请求上重新定义默认范围。 在开发过程中,每个请求都会加载类,以便于开发:代码中的每个更改在下一个请求中都是可见/活动的。

如果您真的想要,可以在生产中禁用此行为。这将使您的完整网站变慢,但也许这不是一个真正的问题。要关闭此功能,您需要修改config/environments/production.rb,找到包含

的行
config.cache_classes = true  

并将其切换为false

希望这有帮助。

答案 2 :(得分:0)

上面的代码没有任何问题,但问题在于使用的服务器,即瘦服务器。用杂物代替薄片后效果很好。我认为除了加载应用程序之外,thin不允许多次执行set_default_scope。