0

環境

ルビー1.9.3p194(2012-04-20リビジョン35410)[x86_64-darwin10.8.0]; Rails 3.2.6; OSX 10.6.8; 考案(2.0.4); forem-redcarpet(1.0.0)

目的

Foremインストール(gem)に追加の注文制御をデプロイする必要があります。おそらく、さらにモデル属性を宣言したいと思うでしょう。そしておそらく、これは次のいずれかで行います。

  1. 基になるForemモデルに名前付きスコープを追加する。
  2. または、基になるモデルをオーバーライドします

質問

どちらをどうすればいいです

4

2 に答える 2

1

回答―デコレータでの異常な実行をどのように説明するか

同僚が私のリクエストを既存のForemドキュメント(Forem:Extending Classes)に指摘しました。これは、次の非常に可能性の高い例外を除いて、この質問にうまく答えることができます。

私が今まで応答しなかった理由は、推奨されるパターンに従う試みが最初は成功しなかったためです。これは、一部の基になるコード(少数の例外)が、モデルクラスをForemエンジンに属するように事前に設定せずに参照したためです。したがって、最初は、このルートはまったく機能していないように見えました。そして(私はまだすべての影響が何であるかはわかりません)、したがって、基礎となるメソッド(「Forem ::」で参照の前に付けられなかった)を「Forem」の形式で改訂された参照でオーバーライドする必要があるように見えました:: ModelName "(" ModelName "ではなく)。

GithubのForemドキュメントページが示すように:

「Foremのすべてのビジネスロジック(モデル、コントローラー、ヘルパーなど)は、標準のRubyイディオムを使用して、正確な要件を満たすように簡単に拡張/オーバーライドできます。

このような変更をアプリケーションまたは拡張機能に含めるための標準的な方法は、ディレクトリアプリ/デコレータを作成することです。関連するapp/decorators/modelsまたはapp/装飾者/controllersディレクトリ内にファイルを配置し、元のクラス名に_decoratorを追加します。」

つまり、コントローラプロセスでさらにインターフェイス値を割り当てるには、Rubyが基になるプロセスを見つけてオーバーライドするそれぞれのディレクトリにデコレータを追加する必要があります。

したがって、 / forem / app / controllers /forem/admin/groups_controller.rbとして存在する元のForemソースのコントローラーは、 / your_project_name /app/デコレーター/コントローラー/forem/admin/groups_controller_decorator.rbによってオーバーライドされます。

以下のコードスニペット(このファイルから)では、元のインデックスメソッドを「index_original」としてエイリアスして、定期的に「index_original」を呼び出します。

Forem::Admin::GroupsController.class_eval do
alias_method :index_original, :index unless method_defined?(:index_original)

def index
    @h_title_of_page = t('h_title2_forum_admin_groups_index')
    @h_description2 = t('h_description2_forums')

    index_original 
    end

ただし、これは機能しませんでした。これは、Foremコントローラーの基になるインデックスメソッドが次の割り当てを行うためです。

@groups = Group.all

したがって、デコレータでindex_originalを呼び出すと、「Group.all」の呼び出しでエラーが発生します。これは、祖先がForemモジュールに属していることを事前に認識しないと認識されないためです。

@groups = Forem::Group.all

したがって、デコレータでこれを修正するには、次のアプローチを取る必要があります(#index_originalは、何を置き換える必要があるかを示すためにコメント化されています)。

def index
    @h_title_of_page = t('h_title2_forum_admin_groups_index')
    @h_description2 = t('h_description2_forums')

    # index_original
        @groups = Forem::Group.all # @groups = Group.all ERROR 
    end

ステートメント「@groups=Forem :: Group.all」は、祖先インデックスメソッドの唯一のステートメントであることに注意してください。したがって、固定ステートメントをデコレータに取り込むことは、メソッドコード全体を独自のデコレータに取り込むことです。これにより、異常な実行が修正されます。これは、祖先インデックスメソッドのこの完全なオーバーライドが、Forem::で始まるモデルへのそれ以上の呼び出しを排除するのに十分であるためです。基になるクラスへのそれ以上の呼び出しの前に置かれていない場合は、それらのメソッドも同様にデコレータに取り込む必要があります。

したがって、独自の(依存する)プロジェクトでこのような潜在的な異常をすべて説明するには、GithubからForemソースをダウンロードし、エイリアスする必要のある基本的なメソッドが、それらのモデルの前にある場合とない場合で、独自のモデルを参照するかどうかを調査する必要があります。 「Forem::」を使用:

  1. 呼び出しているForemプロセスによって呼び出されたすべての呼び出されたモデルの前にある場合、私の努力は、元のメソッドへの呼び出しをエイリアスできることを示しています(たとえば、index_originalなど)。
  2. ただし、プロセス内のForemモデルへの基になる呼び出しの前に「Forem ::」が付いていない場合、私の努力は、基になるmethodSのすべてのコードを(上記のように)デコレータにプルする必要があることを示しています。

うまくいけば、将来的には、Rubyがそのような参照を認識するか、Foremの作成者が内部への参照の前に付けるようになります(Forem開発環境では、コードが明らかに完全に実行されるはずですが)

于 2012-09-29T19:59:05.967 に答える
0

ええと...私は1を提案します(確かに私はその答えを持っているので;-))

これをautoload_pathsに入れます:

extend_it.rb

require 'active_support/concern'

module ExtendIt
  extend ActiveSupport::Concern

  included do
    scope :extension_scope, where(:name => "Mr. X")
  end

  module ClassMethods
  end
end      

初期化子では次のようになります。

extend_it.rb

AnyClass.send :include, ExtendIt

AnyClassもちろん、ターゲットクラスの1つはどこにありますか。詳細については、http://api.rubyonrails.org/classes/ActiveSupport/Concern.htmlを参照してください。

于 2012-09-24T08:45:37.903 に答える