Rails Route の一部としてのパラメータ名と値 (独立して)
-
19-08-2019 - |
質問
DocumentsController#common_query は、複数の異なるリクエスト スタイルを処理できます。
つまりバッチ 4 のすべてのドキュメント、または「ハッピー」タグが付けられたすべてのドキュメント
単一のルートでそれらを美しくしたいので、次のようにします。
/documents/common_query?batch=4
/documents/common_query?tag=ハッピー
なる:
/ドキュメント/バッチ/4
/ドキュメント/タグ/ハッピー
最終結果は、#common_query が呼び出されますが、URL の一部がパラメータ名として使用され、一部がその値として使用されます。
解決
単一のルートとして:
ActionController::Routing::Routes.draw do |map|
map.connect "documents/:type/:id", :controller => "documents_controller",
:action => "common_query"
end
その場合、params[:type]
は"batch"
または"tag"
であり、params[:id]
は"4"
または"happy"
のいずれかです。これは、ルート内でDocumentsController
のその他のアクションがこの前に来るようにする必要があります。これは、"documents/*/*"
のようなURLに一致するためです。
しかし、なぜそれは単一のルートでなければならないのですか?次のような2つのルートを使用できます。
map.with_options(:controller => "documents_controller",
:action => "common_query") do |c|
c.connect "documents/batch/:page", :type => "batch"
c.connect "documents/tag/:tag", :type => "tag"
end
同じ効果がありますが、より具体的であるため、ルートの優先順位について心配する必要はありません。
他のヒント
2 つのルートを持つ 2 番目のオプションは、サポートする URL の種類のみに一致するのに対し、最初のオプションは /documents/foo/bar のような URL にも「一致」するため、ほぼ確実により良い方法です。これにより、#common_query メソッドはせいぜい RecordNotFound (404) 応答を返すことになるでしょう。最悪の場合、予期されるパラメータが表示されないという準備ができていない場合は、代わりに 500 エラーが発生します。
もちろん、バリエーションをたくさん持ち始めると、ルートの数も多くなります。これらを組み合わせて使用する必要がある場合 (/documents/batch/4/tag/happy など)、ワイルドカード ルートを使用し、コントローラーでパラメーター処理を行う必要があります。これは次のようになります。
map.connect 'documents/*specs', :controller => "documents_controller", :action => "common_query"
URL のさまざまな要素は、コントローラーで params[:specs] として使用できます。これを次のような検索に変えることができます。
@items = Item.find(:all, :conditions => Hash[params[:specs]])
その Hash[] テクニックは、オプションの 1 次元配列をキーと値のハッシュに変換します。これは、それを find() に直接供給していない場合でも役立つ可能性があります。