LoginSignup
43
37

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-04-03

はじめに

とある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オプションを利用することで、簡単に導入することができ、その結果

  • 責務に応じたコントローラー分割
  • シンプルなコードの実現

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

参考

43
37
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
37