Edited at

DHH流ルーティングの導入しようとした際にハマったこと

More than 1 year has passed since last update.


はじめに

とあるWebアプリケーションで、通常のお知らせ、メンテナンス情報、障害情報の三種類のお知らせを表示させるために

class InformationsController < ApplicationController

def index
end

def maintenance
end

def trouble
end
end

ようなコントローラーを作成したとします。規則性のないメソッド名やコントローラーの肥大化など問題に発展しやすいです。

そこで、DHHはどのようにRailsのコントローラを書くのかの記事では、DHH流のルーティングを学ぶことで、本問題の解決法が提示されています。このDHH流ルーティングを導入しようとした際に、ハマったことをまとめます。


DHH流ルーティングとは

翻訳記事によると


  • RESTの原則に従う場合は、全てのコントローラーで例外なくその原則に従うべき

  • 全てのコントローラーでは、デフォルトCRUDのindex , show, new, edit, create, update, destroyメソッドのみを持つこと

  • 例えばメールボックの受信一覧とペンディング一覧を閲覧するアクションを持つコントローラーを作る場合は、以下のように indexpendingsアクションを作るのではなく、

class InboxesController < ApplicationController

def index
end

def pendings
end
end

index という単一のメソッドだけを持つInboxes::PendingsControllerを作成する。これにより独自のスコープとフィルターを提供することができるようになる。

class InboxesController < ApplicationController

def index
end
end

class Inboxes::PendingsController < ApplicationController

def index
end
end


ルーティングを設定する

先程の InboxesControllerInboxes::PendingsControllerを実現するため、以下3パターンを試しました。


resourcesのネスト


config/routes.rb

  resources :inboxes, only: [:index] do

resources :pendings, only: [:index]
end

$ rails routes

Prefix Verb URI Pattern Controller#Action
inbox_pendings GET /inboxes/:inbox_id/pendings(.:format) pendings#index
inboxes GET /inboxes(.:format) inboxes#index

inbox_pendings側をみると、URIパターンは希望通りですが、Controller#Actioninboxes/pendings#indexとなってくれません。


namespace

次に namespace でネストさせます。


config/routes.rb

  resources :inboxes, only: [:index]

namespace :inboxes do
resources :pendings, only: [:index]
end

$ rails routes

Prefix Verb URI Pattern Controller#Action
inboxes GET /inboxes(.:format) inboxes#index
inboxes_pendings GET /inboxes/pendings(.:format) inboxes/pendings#index

Controller#Actionは希望通り、inboxes/pendings#indexとinboxesディレクトリ配下となりましたが、URIパターンを見ると、:inbox_idが消えてしまいました・・・。


resourcesのネストとmodule指定


config/routes.rb

  resources :inboxes, only: [:index] do

resources :pendings, only: [:index], module: 'inboxes'
end

$ rails routes

Prefix Verb URI Pattern Controller#Action
inbox_pendings GET /inboxes/:inbox_id/pendings(.:format) inboxes/pendings#index
inboxes GET /inboxes(.:format) inboxes#index

先程のresourcesのネストは同じですが、moduleオプションを付けることで、名前空間が設定でき、inboxesディレクトリ配下にpendings_controllerが作成できるになり、ファイル配置もすっきりさせることができるようになりました。


終わりに

resoucesとmoduleオプションを利用することで、簡単に導入することができ、その結果


  • 責務に応じたコントローラー分割

  • シンプルなコードの実現

という効果が得られるので、積極的に取り入れていきたいです。


参考