1

私は、単一の 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

しかし、それは役に立ちませんでした。ここでスコーピングに関する知識が不足していると感じます。何が悪いのか考えはありますか?前もって感謝します。

4

2 に答える 2

0

問題で言及されている初期計画に固執する方法についての解決策を最終的に思いつきましたが、「クラスキャッシング」の問題はありません。

これは、このトピックに関する別の質問への回答に基づいています。

とにかくここに新しい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 を介してそれらにアクセスすることにしました。

どこでも使えるので、applicationControllerShop.current.nameShop.current.taxspec_helperで設定したショップに対応しています。

于 2013-03-09T21:45:01.360 に答える
0

クラス属性が次に更新されるまで保持されるべきではない理由はありません。

Rails アプリの開発モードでは、コードが変更されたときにコードがリロードされるため、これらのクラス変数がリセットされるという副作用がありますが、それに依存したくはありません。

before フィルターがすべきことは、現在のリクエストに使用するショップを含む @current_shop インスタンス変数を設定することです。

于 2013-03-09T09:41:25.713 に答える