首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在请求之间重置ruby类访问器?

如何在请求之间重置ruby类访问器?
EN

Stack Overflow用户
提问于 2013-03-09 10:13:29
回答 2查看 149关注 0票数 1

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

在那里,我有一个类来保存特定于商店的设置。

代码语言:javascript
复制
# 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文件,以防万一:

代码语言:javascript
复制
# config/shop.yml
shop_1:
  shop_name: Shop 1
shop_2:
  shop_name: Shop 2

我在应用程序控制器中通过域名匹配所请求的商店。

代码语言:javascript
复制
# 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

代码语言:javascript
复制
Shop.shop_name # => Shop 1

shop2.com

代码语言:javascript
复制
Shop.shop_name # => Shop 1

它会保留初始设置,直到我对application_controller.rb或shop.rb进行一些更改。(我认为这是答案的第一个关键)

我所知道的是,Settingslogic为shop.yml中的每个选项定义了attr_accessor (只在第一次被调用时)。但为什么它们在重新加载后仍然有效(我在cache_classes =false的开发环境中工作)

当我这样做的时候:

代码语言:javascript
复制
# models/shop.rb
class Shop < Settingslogic
  source "#{Rails.root}/config/shop.yml"
  namespace  "shop_#{Random.rand(1..2)}"
  load!
end

它的工作与预期一样-每次都会加载适当的设置。但是我不能在这个舞台上按域名设置店名。此外,当我不能从外部指定shop_name时,我也不能测试不同的商店。所以我需要一个方法。

我试过class_eval

代码语言:javascript
复制
def self.init!(shop)
  class_eval do
    namespace shop.to_s
    load!
  end
end

但这并不管用。我觉得这里缺乏作用域方面的知识。你知道出什么问题了吗?提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-09 17:41:26

没有理由不保留类属性,直到下次更新它们。

在rails应用程序的开发模式中,当代码发生更改时会重新加载代码,这将产生重置这些类变量的副作用,但您不希望依赖于此。

之前的过滤器应该做的是设置一个@current_shop实例变量,该变量包含要用于当前请求的商店。

票数 0
EN

Stack Overflow用户

发布于 2013-03-10 05:45:01

我最终想出了一个解决方案,如何坚持问题中提到的初始计划,但又不存在“类缓存”问题。

它基于对my another question在此主题上的回答。

不管怎样,这是新的Shop.rb

代码语言:javascript
复制
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.nameShop.current.tax,它对应于在applicationController或spec_helper中设置的商店。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15306406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档