6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails/ルーティング】自作したディレクトリ内のコントローラを参照する方法

Last updated at Posted at 2020-11-01

概要

かんたんログイン(テストユーザーログイン)実装にあたり、普段しない形でコントローラファイルを作成しました。

その際に「え、これどうなってんの?」と感じたことがあったのでそれを記録します。


環境

  • macOS Catalina 10.15.6

  • ruby 2.6.5

  • Rails 6.0.3.4

  • MySQL : 5.6.47


今回やりたいこと

  • [URL] localhost:3000/admin/usersにアクセス

  • app/controllers/admin/users_controller.rbのindexアクションへルーティング

  • index.html.erbを表示


まず、普通のusersコントローラで動作確認

ターミナルで以下のコマンドを入力します。

% rails _6.0.0_ new controller-app -d mysql

% cd controller-app

% rails db:migrate

% rails g controller users

また、ルーティングは以下の通り設定します。

app/config/routes.rb

Rails.application.routes.draw do
  resources :users, only: :index
end
HTTP Verb URI Pattern Controller#Action
GET /users users#index

そしてコントローラにindexアクションを追加します。

app/controllers/users_controller.rb
class UsersController < ApplicationController

  def index
  end

end

最後に、ビューを追加します。

app/views/index.html.erb

<h1>users#index</h1>

これで準備完了。
試しに'/users'にアクセスすると…

demo


普通にビューが表示されました!

では、ここから手を加えていきます!



コントローラをadminディレクトリに移動

1. adminディレクトリに移動すると?

  • app/controllers/adminディレクトリを作成

  • その中にusers_controller.rbを移植

  • '/users' にアクセスしてみる

demo

uninitialized constant UsersControllerというルーティングエラーが出ています。
これは「定数やクラスが定義されていないエラー」です。


現状を整理すると、

  • GET '/users' をリクエスト

  • users#index (usersコントローラ) を探す

  • そんなのないよ!というエラー


ん?もう一度usersコントローラを見てみましょう。

app/controllers/admin/users_controller.rb
class UsersController < ApplicationController

  def index
  end

end

class UsersControllerって書いてるじゃん!
と言いたいところですが、これはシンプルに記述のミスです。

どういうことかというと…

  • 今のルーティングの定義だと app/controllers ディレクトリ直下のコントローラファイルを探す

  • ルーティング参照先を app/controllers/admin ディレクトリ直下に変更する必要がある

さて、これをどう実現するか?
次で説明します。


2. namespaceをルーティングに設定

こちらのRailsガイドの2.6を参照しました。

app/controllers/adminディレクトリのコントローラを参照したい際は、次のようにルーティングを設定します。

app/config/routes.rb
Rails.application.routes.draw do
  namespace :admin do
    resources :users, only: :index
  end
end
HTTP Verb URI Pattern Controller#Action
GET /admin/users admin/users#index

これでadminディレクトリのusersコントローラを参照できるようになりました。

では、実際に'admin/users'にアクセスしましょう!

demo

だめですか…。
とりあえずエラー文を解読しましょう。


expected file /Users/***/app/controllers/admin/users_controller.rb to define constant Admin::UsersController, but didn't

  • 定数Admin::UsersControllerを定義するため

  • /Users/***/admin/users_controller.rb というファイルが必要

  • でも定義せんかったわ


現状、admin/users_controller.rbは指定のパスに入っています。
なのでここで出てきたAdmin::UsersControllerをクラス名に定義すれば良さそうです。


というわけでコントローラを以下のように変更します。

app/controllers/admin/users_controller.rb
class Admin::UsersController < ApplicationController

  def index
  end

end

これでどうでしょう?


demo


まだダメでした。もうひと作業必要なようです。
もう少し頑張りましょう!


3. ビューファイルを移動

さて、先程のエラー文を解読します。

  • Admin::UsersController#index is missing a template for request formats

  • Admin::UsersController#indexはリクエストフォーマットに対応するテンプレートがありません


リクエストフォーマットって何?と思いましたが、続く小さい文字にヒントがありました。

  • Unless told otherwise, Rails expects an action to render a template with the same name, contained in a folder named after its controller.

  • 特に明記されてなければ、Railsは同じ名前のテンプレートをレンダリングするアクションを想定しています

  • コントローラにちなんで名付けられたフォルダに含まれています


つまり「Admin::UsersControllerがレンダリングするビューがないよ」ということです。
そしてそのファイルはコントローラ名に対応したディレクトリに配置する必要がありそうです。

少し具体的に考えると、

  • UsersControllerのindexアクションは

  • app/views/users/index.html.erbのビューをレンダリングする


よって、今回のケースでは、

  • Admin::UsersControllerのindexアクションなので

  • app/views/admin/users/index.html.erb


にビューファイルをセットすればいいと考えられます。

というわけで変更します!

app/views/admin/users/index.html.erb

<h1>admin/users/index.html.erb</h1>

さあ、どうでしょうか。


demo


やりました!これで目的達成です!


まとめ

app/controllersにディレクトリを作ってコントローラファイルを配置するときの注意

  1. ルーティングにnamespaceを設定

  2. クラス名をAdmin::UsersControllerのように変更 (ディレクトリ名を追加)

  3. 同名ディレクトリ直下にビューファイルを設置


これで実現できます。

ちなみに、今回のケースではURLが変わってしまいました。
これはnamespaceの代わりにmoduleを設定すればURLはそのままになります。

app/config/routes.rb

Rails.application.routes.draw do
  scope module: :admin do
    resources :users, only: :index
  end
end
HTTP Verb URI Pattern Controller#Action
GET /users admin/users#index

勉強になりました!これからも地道にRailsのことを学習していきます!

参照

6
2
0

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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?