私は、単一の Rails アプリケーション内でいくつかの異なるショップを提供する e コマース ソリューションに取り組んでいます。
そこには、ショップ固有の設定を保持するクラスがあります。
# models/shop.rb
class Shop < Settingslogic
source "#{Rails.root}/config/shop.yml"
def self.init!(shop)
namespace shop.to_s
load!
end
end
ショップ::初期化! 設定ファイルから指定されたセクションを読み込みます
念のため、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 = 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
しかし、それは役に立ちませんでした。ここでスコーピングに関する知識が不足していると感じます。何が悪いのか考えはありますか?前もって感謝します。