2013-03-09 64 views
1

我正在開發電子商務解決方案,該解決方案在單個導軌應用程序內提供幾個不同的商店。如何在請求之間重置ruby類訪問器?

在那裏我有一個類來舉辦商店特定的設置。

# models/shop.rb 
class Shop < Settingslogic 
    source "#{Rails.root}/config/shop.yml" 

    def self.init!(shop) 
    namespace shop.to_s 
    load! 
    end 

end 

Shop :: 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 1 

shop2.com

Shop.shop_name # => Shop 1 

而且它保持初始設置,直到我做了一些更改爲application_controller.rb或shop.rb. (我認爲這是答案的第一個關鍵)

我所知道的是Settingslogic爲shop.yml中的每個選項定義attr_accessor(僅當第一次調用時)。但是,爲什麼他們重​​裝後仍能正常工作

(我在開發環境與cache_classes =假工作)當我這樣做的方法:

# 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 

,但它並沒有幫助。我覺得缺乏這方面的範圍知識。 你有什麼想法嗎?提前致謝。

+2

如果你有很多商店,你爲什麼使用單件商店代替多個商店實例? – 2013-03-09 03:55:28

+0

@AndrewMarshall,因爲應用程序不知道有其他商店。它只需要訪問店鋪特定的設置,例如它是Settingslogic子類的常規設置模型。 唯一的區別是我根據'request.domain'加載了不同的設置文件部分。 – 2013-03-09 11:01:40

+0

@AndrewMarshall謝謝。當我意識到什麼是問題時,您的回答幫助我意識到我需要每個請求都有一個新的Shop實例。 – 2013-03-09 11:30:22

回答

0

沒有理由不應該保留類屬性,直到他們下次更新。

在Rails應用程序的開發模式中,當代碼發生更改時會重新加載代碼,這會重置這些類變量的副作用,但您不想依賴該代碼。

您之前的過濾器應該做的是設置一個@current_shop實例變量,其中包含用於當前請求的商店。

+0

是的,如果我只需要店名,@current_shop就可以。我只是簡化了我的配置文件。 有跡象表明,應該在應用程序的不同地方訪問的其他選項: 'Shop.layout' - 在控制器或意見 'Shop.tax' - 在模型 'Shop.email.general' - 在郵寄 等 – 2013-03-09 11:09:21

+0

我正在寫關於類緩存的第二個評論,並意識到整個方法是錯誤的,可能也是我的問題。無論我是直接在類中調用'load!',還是將其封裝在'init!'方法中,它都不會像我在生產中預期的那樣工作。謝謝你的回答。 – 2013-03-09 11:23:41

+0

你可以使用線程本地化的Shop.current方法,你可以在任何地方使用 – 2013-03-09 11:31:04

0

我終於想出了一個關於如何堅持提到的初始計劃的解決方案,但沒有「類緩存」問題。

它基於對該主題的回答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.nameShop.current.tax,它對應於在applicationController或spec_helper中設置的商店。

相關問題