2

我知道这是关于全局对象的第 1001 个问题,但我认为我的情况略有不同。

我正在研究电子商务解决方案,它在单个 Rails 应用程序中提供了几个不同的商店。

有一个类 Shop 提供特定于商店的逻辑和选项。例如:

@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

我知道不应该在模型中使用基于请求的逻辑,但我确实需要那里的商店选项。在测试中,我可以像Shop.new(:test_shop)在 spec_helper 中那样模拟这个“全局”对象。

全局变量是我唯一的选择吗?我从来没有用过它们。

我尝试使用 Settingslogic gem,但它为特定于商店的选项定义了 attr_accessors,并且它们在请求之间持续存在,这不是我所需要的。

4

1 回答 1

1

这样做的一种方法是

class Shop
  def self.current=(shop)
    Thread.current[:current_shop] = shop
  end

  def self.current
    Thread.current[:current_shop]
  end
end

这允许您为每个请求维护一个单独的当前商店。

另一种方法是绕过当前的商店。起初它可能看起来很乏味,但最终可能比全局或伪全局行为更容易推理

于 2013-03-09T12:59:32.243 回答