我知道这是关于全局对象的第100个问题,但我认为我的情况略有不同。
我正在开发电子商务解决方案,它在单个rails应用程序中提供了几个不同的商店。
有一个类商店,提供商店特定的逻辑和选项。例如:
应该可以在模型中访问 @shop.tax
。税收可能因商店而异。例如9%,18%。
@shop.name
和@shop.layout
。
@shop.email.general
。
我需要能够在应用程序控制器中创建Shop的实例,并以某种方式将其传递给所有应用程序部分。
# controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_shop
protected
def set_shop
requested_shop = if request.domain.match(/^.*shop1\.com$/)
:shop_1
elsif request.domain.match(/^.*shop2\.com$/)
:shop_2
end
@shop = Shop.new(requested_shop)
end
end
我知道基于请求的逻辑不应该用在模型中,但我真的需要那里的商店选择。在测试中,我可以像spec_helper中的Shop.new(:test_shop)
一样模拟这个“全局”对象。
全局变量是我唯一的选择吗?我从来没有用过它们。
我尝试使用Settingslogic gem,但它为商店特定的选项定义了attr_accessors,并且它们在请求之间保持不变,这不是我需要的。
答案 0 :(得分:1)
这样做的一种方法就是
class Shop
def self.current=(shop)
Thread.current[:current_shop] = shop
end
def self.current
Thread.current[:current_shop]
end
end
这使您可以为每个请求维护一个单独的当前商店。
另一种方法是通过现有的商店。一开始可能看起来很乏味,但最终可能比全局或伪全球行为更容易推理