Help us understand the problem. What is going on with this article?

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

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

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

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away