nestされたresourcesでのcontrollerの指定

nestされたresoucesでのController

1対多などの関連を持つmodelをそれぞれ直接操作したい時があります。
その場合は、それぞれのmodelに対してcontrollerを作成し、CRUDなどの操作を行います。

それとは別に1対多のリソースの関係をURLに反映したい場合もあります。
例えば、author has many postsだった場合、特定のauthorが持つpostsの一覧は以下のようなURLになると思います。

1
/authors/:author_id/posts

このURLを実現するために、routingの設定は以下のようにします。

1
2
3
resources :authors do
resources :posts
end

ただ、この設定をrails routesで確認すると、先ほど記載したURL(authorにぶら下がったposts)のControllerは、posts#indexとなってしまい、authorにぶら下げないpostsと同じControllerになってしまいます。

対処法

このままだとposts_controller.rbにいろんなメソッドを追加しないといけなくなってしまうので、authorにぶらさがるpostsを処理するControlerは別で定義したいと思います。

ディレクトリの作成

app/controllersの下にauthorsというディレクトリを作成します。このディレクトリの配下にauthorにぶら下がるリソースのControllerを作成していきます。

Controllerの作成

先ほど作成したauthorsの下にposts_controller.rbを作成します。
app/controllers配下のposts_controller.rbの違いとしては、namespaceを持っているということです。

1
2
3
4
module Authors
class PostsController < ApplicationController
end
end

routingの設定

現在のroutingの設定に、作成したControllerを指定します。

1
2
3
resources :authors do
resources :posts, controller: "authors/posts"
end

まとめ

以上でnestされたresourcesに対応するControllerを設定することができました。
こういったmodelの関連を表すURLはよく作成するので忘れないようにしたいと思います。