我正在研究电子商务解决方案,它在单个rails应用程序中提供了几个不同的商店。
在那里,我有一个类来保存特定于商店的设置。
# models/shop.rb
class Shop < Settingslogic
source "#{Rails.root}/config/shop.yml"
def self.init!(shop)
namespace shop.to_s
load!
end
end商店::init!从配置文件中加载指定节
以下是yml文件,以防万一:
# config/shop.yml
shop_1:
shop_name: Shop 1
shop_2:
shop_name: Shop 2我在应用程序控制器中通过域名匹配所请求的商店。
# controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_shop
protected
def set_shop
Shop.init! if request.domain.match(/^.*shop1\.com$/)
:shop_1
elsif request.domain.match(/^.*shop2\.com$/)
:shop_2
end
end
end问题是,Shop以某种方式在请求之间保留了第一个请求的商店的设置。例如:
shop1.com
Shop.shop_name # => Shop 1shop2.com
Shop.shop_name # => Shop 1它会保留初始设置,直到我对application_controller.rb或shop.rb进行一些更改。(我认为这是答案的第一个关键)
我所知道的是,Settingslogic为shop.yml中的每个选项定义了attr_accessor (只在第一次被调用时)。但为什么它们在重新加载后仍然有效(我在cache_classes =false的开发环境中工作)
当我这样做的时候:
# models/shop.rb
class Shop < Settingslogic
source "#{Rails.root}/config/shop.yml"
namespace "shop_#{Random.rand(1..2)}"
load!
end它的工作与预期一样-每次都会加载适当的设置。但是我不能在这个舞台上按域名设置店名。此外,当我不能从外部指定shop_name时,我也不能测试不同的商店。所以我需要一个方法。
我试过class_eval
def self.init!(shop)
class_eval do
namespace shop.to_s
load!
end
end但这并不管用。我觉得这里缺乏作用域方面的知识。你知道出什么问题了吗?提前谢谢。
发布于 2013-03-09 17:41:26
没有理由不保留类属性,直到下次更新它们。
在rails应用程序的开发模式中,当代码发生更改时会重新加载代码,这将产生重置这些类变量的副作用,但您不希望依赖于此。
之前的过滤器应该做的是设置一个@current_shop实例变量,该变量包含要用于当前请求的商店。
发布于 2013-03-10 05:45:01
我最终想出了一个解决方案,如何坚持问题中提到的初始计划,但又不存在“类缓存”问题。
它基于对my another question在此主题上的回答。
不管怎样,这是新的Shop.rb
class Shop < Settingslogic
source "#{Rails.root}/config/shop.yml"
load!
def self.current=(shop)
Thread.current[:current_shop] = shop.to_sym
end
def self.current
self.send(Thread.current[:current_shop])
end
end我决定加载shop.yml的所有部分,并通过Shop::current访问它们,它将调用转发到适当的部分。
所以我可以在任何地方使用Shop.current.name和Shop.current.tax,它对应于在applicationController或spec_helper中设置的商店。
https://stackoverflow.com/questions/15306406
复制相似问题