[Rails] 動的なパスをつけたルーティングの指定方法

サービスを作っていると、マスター管理された文字列を利用してパスを切り分けたいことがよくあります。たとえば、顧客ごとに、customer_a/awesome/path,customer_b/awesome/pathのようなイメージです。

この記事ではRailsでこのように動的にパスを切り替えるルーティングの記述方法について、解説しています。

問題点

マスター管理された文字列でシステムを切り分けたいことがあると思います。
例えば、Categoryモデルに登録された値を用いてURLを/:category_name/postsといったものにしたい時、1つだけであれば、routes.rbの設定は以下のもので十分です。

match '/:category_name/posts', to: 'posts#index', via: 'get'

しかし、これが複数になっていったとき、以下のように書くのはあまりにも冗長です。

match '/:category_name/posts', to: 'posts#index', via: :get
match '/:category_name/posts/:id', to: 'posts#show', via: :get
match '/:category_name/posts/new', to: 'posts#new', via: :get
match '/:category_name/posts', to: 'posts#create', via: :post
match '/:category_name/posts/:id', to: 'posts#destroy', via: :delete

このルーティングを簡潔に書くための方法をご紹介します。

方法

以下のようにscopeでくくるだけでOKです。

scope '/:category_name' do
  resources :posts, only: [:index, :show, :new, :create, :destroy]
end

scopeの中に通常通りのroutingの設定を書いていけば、パスの頭に/:category_nameがついて、controller内でparams[:category_name]として呼び出すことができます。

まとめ

config/routes.rbを見れば、どんな機能があるのかオーバービューが分かります。後からジョインする開発メンバーのためにも、特にルーティングは明快でメンテナンスしやすいコードにしてやるのが得策だと思います。