3

ポリモーフィックなモデル Report があります。私のサイトの非常に多くの itens には、その多くが含まれている可能性があります。

そして、それを投稿するための汎用コントローラーが必要です。非常に単純なモデルで、テキスト メッセージと関連付けのみが含まれます。

私のルートでは、私は次のようなことをしています

map.resources :users, :has_many => [ :reports ]
map.resources :posts, :has_many => [ :reports ]

しかし、私のreports_controllerでは、関係を取得したいと思います。

お気に入り:

before_filter :get_reportable

def get_reportable
   reportable = *reportable_class*.find params[:reportable_id]
end

これは可能ですか?

reportable_class と reportable_id を取得するにはどうすればよいですか?

ユーザーコントローラーからの場合は params[:user_id] を、投稿からの場合は params[:post_id] を取得できます。私はすべての関係でケースを実行できますが、それはまったくきれいな解決策ではないようです...

ポリモーフィックな関連付けを持つことが最善ですが、方法はありますか?

4

2 に答える 2

4

2つの異なるパスを介してリクエストを処理する単一のコントローラがある場合は、それが呼び出されるコンテキストを認識させる必要があります。次のようなコードがよく見られます。

before_filter :load_reportable

def load_reportable
  if (params[:user_id])
    @user = User.find(params[:user_id])
    @reportable = @user
  elsif (params[:post_id])
    @post = Post.find(params[:post_id])
    @reportable = @post
  end
rescue ActiveRecord::RecordNotFound
  render(:partial => 'not_found', :status => :not_found)
  return false
end

ポリモーフィックアソシエーションを使用しているため、代わりに次のようなことができる場合があります。

before_filter :load_reportable

def load_reportable
  unless (@reportable = @report.reportable)
    # No parent record found
    render(:partial => 'not_found', :status => :not_found)
    return false
  end

  # Verify that the reportable relationship is expressed properly
  # in the path.

  if (params[:user_id])
    unless (@reportable.to_param == params[:user_id])
      render(:partial => 'user_not_found', :status => :not_found)
      return false
    end
  elsif (params[:post_id])
    unless (@reportable.to_param == params[:post_id])
      render(:partial => 'post_not_found', :status => :not_found)
      return false
    end
  end
end

2つのまったく異なるルートを処理する1つのコントローラーがあるこのアプローチの問題は、「ユーザーが見つかりません」と「投稿が見つかりません」などのエラーメッセージを生成することです。たとえば、Users :: BaseControllerから継承していない場合、これを正しく行うのは難しい場合があります。

多くの場合、ユーザー/レポートと投稿/レポートなど、2つの独立した「レポート」コントローラーを作成する方が簡単です。ここでは、一般的な機能がモジュールからインポートされます。これらのコントローラーは通常、ロードとエラー処理を実行するベースコントローラーから継承します。ベースコントローラーは、サブリソースコントローラーごとにこの機能を再実装しなくても、レイアウトやページタイトルなどを確立できます。

別の方法は、レポートを切り離して、「レポート可能な」レコードとの関係がほとんど関係のない独自のコントローラーとして実行することです。

于 2010-01-15T15:41:59.903 に答える
0

またはそれを試してください:

before_filter :get_reportable

def get_reportable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      @reportable = $1.classify.constantize.find(value)
    end
  end
end

すべてのパラメーターを調べて、_id で終わるものを見つけようとし、その前にそれを取得して、関連するレコードを見つけます。

于 2012-01-09T11:14:35.910 に答える