-1

私は Page と呼ばれる基本モデルを持っており、次のような Page に基づいた多くの STI モデルを持っています。

描く

論文

等...

モデル タイプに基づいてビュー レイヤーをカスタマイズする必要があり、コントローラーに異なるロジックを使用する必要があったため、これらの STI モデルごとに個別のコントローラーとビューを用意しました。ただし、すべてのモデルの作成者フィールドを現在のユーザーに設定する必要があります。これを 1 か所で行うにはどうすればよいですか。

たとえば、Page コントローラーで before_action を使用して作成者を設定すると、@page インスタンス変数に影響しますが、DrawingsController は @drawing を使用しているため、DrawingsController で同じコードを繰り返さない限り、@drawing の作成者は保存されません。

編集:

私のコントローラー階層は

DrawingsController < PagesController

PagesController < ApplicationController

PagesController と DrawingsController の両方に、7 つの安静なアクションすべてがあります。ただし、ユーザーにページを作成させたくないため、PagesController のアクションは何の目的も果たしません。Drawings のような継承された STI クラスだけを作成してもらいたいのです。

4

2 に答える 2

0

正直なところ、この回答の「ベストプラクティス」については保証しませんが、ある程度役立つ場合に備えて提案します。また、問題を再考した後、コメントで最初に提案された解決策が間違っていて、2番目の解決策も正しくないことに気付きました. だから私は2番目の提案の修正版のみを投稿しています:

短い答え:ほとんどPagesControllerの作業を処理し、必要に応じてモデル固有のものについてのみサブコントローラーに委任します。phoet が言ったように、(別の方法で) メタ プログラミングを少し使用して、これを実現できます。

class PagesController < ApplicationController
    # pages controller stuff here
    def create
        @page = controller_name.classify.constantize.new(params[:page_params]) # I love Rails, don't you?
        @page.author = current_user
        handle_additional_create_actions 

        # For completeness of this example...
        if @page.save
            # render / redirect on success
        else
            # render errors
        end
    end
protected

    # This method should be overwritten by sub controllers if needed
    # Also, name this whatever you like, this is merely a verbose example for illustration purposes
    def handle_additional_create_actions
        # in the pages controller, this method does nothing
    end
end

また、モデル固有のコントローラーで実行する必要がある追加のことがある場合:

class DrawingsController < PagesController
    # drawing controller stuff here

protected
    def handle_additional_create_actions
        @page.some_other_field = some_other_data
    end
end

簡単なメモ: 私の提案では、モデル固有の変数名を削除していることに注意してください。つまり、@drawing@articleなどはもうありません。モデルはすべて、基本的にはPageオブジェクトの型であるため、慣例として一般的な名前で呼びます。DrawingsControllerこうすることで、クラス固有の処理をに依頼すると、一般的な名前のオブジェクトDrawingを介してインスタンスにアクセスできることがわかります。@page

したがって、最終的には、PagesController扱っている具体的なモデルの種類に関係なく、 が面倒な作業を行います。そうすれば、一般的なページのものだけがページコントローラーで見つかり、描画、記事、またはストーリー固有のものはそれぞれの具象コントローラーで見つかります。

于 2013-11-08T16:21:50.777 に答える