質問

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() に直接供給していない場合でも役立つ可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top