7

2つの名前空間があり、それぞれに独自のコントローラークラスとプレゼンタークラスがあります。 Member::DocumentsController Member::DocumentPresenter Guest::DocumentsController Guest::DocumentPresenter

両方のプレゼンターはから継承し::DocumentPresenterます。

コントローラは、名前空間を指定せずにそれぞれのプレゼンターにアクセスします。例:

class Guest::DocumentsController < ActionController::Base
    def show
        DocumentPresenter.new(find_document)
    end
end

これは通常、同じ名前空間内でプレゼンターを呼び出します。ただし、開発環境では、ベース::DocumentPresenterが使用されていることがあります。

原因は、ベース:: DocumentPresenterがすでにロードされているためだと思われます。そのため、Railsクラスの自動ロードはわざわざそれ以上調べる必要はありません。これはおそらくそうですか?実稼働環境でも発生する可能性はありますか?

私は2つの解決策を考えることができます:

  • 基本クラスの名前をDocumentPresenterBaseに変更します
  • コントローラファイルに適切なプレゼンターファイルを明示的に要求する

より良い解決策はありますか?

4

2 に答える 2

3

仮定は正しいです-名前空間を指定しない場合、Rubyは現在の名前空間から開始し、クラスを見つけるために作業を進めます。名前空間クラスはまだ自動ロードされていないため、::DocumentPresenterが検出され、オートローダーはトリガーされません。

解決策として、名前空間を忘れたり、どこかで明示的に要求したりするときにバグから保護するため、名前をに変更::DocumentPresenterすることをお勧めします。DocumentPresenterBase

考慮すべき2番目のオプションは、実際にはあちこちで特定の名前空間クラス名を使用することですが、誤って名前空間を指定し忘れた場合、バグが発生します。

class Guest::DocumentsController < ActionController::Base
  def show
    Guest::DocumentPresenter.new(find_document)
  end
end 

3番目のオプションは2番目になります-事前に初期化子のすべてのクラスを明示的に要求します。私はこれをRailsAPIで行いました。これは、埋め込まれたモデルを受け取りJSON、実際のモデルがまだロードされていないときにRailsが名前空間を付ける傾向があります。

オプション3.5オートローダーをだまして手間のかかる作業を行うこともできます(ただし、これはハックのように見えるかもしれません)。

class Guest::DocumentsController < ActionController::Base

  # trigger autoload
  Guest::DocumentPresenter

  def show
    # This should refer Guest::DocumentPresenter
    DocumentPresenter.new(find_document)
  end

  def show
    # As will this
    DocumentPresenter.new(find_document)
  end
end 

それでも最もクリーンなのは、基本クラスの名前を変更することです。

于 2012-11-05T16:45:58.847 に答える
1

名前をマンテインしたい場合は、3つのソリューションで、1つが2番目のソリューションだと思います。

1)コントローラーファイルに適切なプレゼンターファイルを明示的に要求する

2)次のような完全な環境クラスパスを実行します。

class Guest::DocumentsController < ActionController::Base
    def show
        Guest::DocumentPresenter.new(find_document)
    end
end

3)初期化ディレクトリにファイルを作成し、requireを手動で実行します(最悪のオプション:S)

于 2012-11-05T16:47:07.070 に答える