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つの独立した「レポート」コントローラーを作成する方が簡単です。ここでは、一般的な機能がモジュールからインポートされます。これらのコントローラーは通常、ロードとエラー処理を実行するベースコントローラーから継承します。ベースコントローラーは、サブリソースコントローラーごとにこの機能を再実装しなくても、レイアウトやページタイトルなどを確立できます。
別の方法は、レポートを切り離して、「レポート可能な」レコードとの関係がほとんど関係のない独自のコントローラーとして実行することです。