[RUBY] [Rails / Routing] How to refer to the controller in the directory you created

Overview

To implement Easy Login (Test User Login), I created a controller file in an unusual way.

At that time, I had a feeling "What's going on with this?", So I will record it.


environment


What I want to do this time


First, check the operation with an ordinary users controller

Enter the following command in the terminal.

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

% cd controller-app

% rails db:migrate

% rails g controller users

Also, set the routing as follows.

app/config/routes.rb



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

Then add an index action to your controller.

app/controllers/users_controller.rb


class UsersController < ApplicationController

  def index
  end

end

Finally, add a view.

erb:app/views/index.html.erb



<h1>users#index</h1>

Now you are ready. When I try to access'/ users' ...

demo


The view was displayed normally!

Let's start from here!



Move controller to admin directory

1. What if I move to the admin directory?

demo

I'm getting a routing error saying `ʻuninitialized constant UsersController``. This is a " constant or class undefined error </ b>".


To summarize the current situation

  • Request GET'/ users'

  • Find users # index (users controller)

  • There is no such thing! Error


Hmm? Let's take a look at the users controller again.

app/controllers/admin/users_controller.rb


class UsersController < ApplicationController

  def index
  end

end

You're writing class UsersController! I would like to say that this is simply a mistake in the description.

What does that mean ...

  • With the current routing definition, look for the controller file directly under the app / controllers directory </ b>

  • You need to change the routing reference to directly under the app / controllers / admin directory </ b>

So how do you achieve this? This is explained below.


2. Set namespace to routing

I referred to 2.6 in this Rails guide.

If you want to reference the controllers in the app / controllers / admin directory, configure the routing as follows:

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

You can now reference the users controller in the admin directory.

Now, let's actually access'admin / users'!

demo

Is it no good ... Let's decipher the error statement for the time being.


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

  • To define the constant Admin :: UsersController

  • Requires a file called /Users/***/admin/users_controller.rb

  • But I didn't define it


Currently, `ʻadmin / users_controller.rb`` is in the specified path. So it seems good to define Admin :: UsersController that appears here in the class name </ b>.


So change the controller as follows.

app/controllers/admin/users_controller.rb


class Admin::UsersController < ApplicationController

  def index
  end

end

How about this?


demo


It was still useless. It seems that another work is needed. Let's do our best!


3. Move the view file

Now, decipher the error statement.

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

  • Admin :: UsersController # index does not have a template for request format


What is the request format? I thought, but there was a hint in the small letters that followed.

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

  • Unless otherwise stated, Rails expects an action that renders a template with the same name.

  • Included in a folder named after the controller


In other words, " Admin :: UsersController has no view to render </ b>". And it seems that the file needs to be placed in the directory corresponding to the controller name.

Thinking a little more concretely

  • The index action of UsersController is

  • Render views in app / views / users / index.html.erb


Therefore, in this case,

  • Because it is the index action of Admin :: UsersController

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


It is thought that you should set the view file in.

That's why I will change it!

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



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

How about now?


demo


Did it! This is the goal!


Summary

Notes on creating a directory in app / controllers and placing controller files </ b>

  1. Set namespace for routing

  2. Change the class name to something like Admin :: UsersController (add directory name)

  3. Place the view file directly under the directory with the same name


This can be achieved.

By the way, the URL has changed in this case. This will leave the URL as it is if you set module instead of namespace.

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

I learned a lot! We will continue to learn about Rails steadily!

reference

Recommended Posts