ruby-on-railsrubynamespacesnested-routes

Rails 5 - nested controllers with routes


I'm trying to make an app in Rails 5.

In order to keep the file structure neat, I'm trying to make folders inside my controllers directory, that I can use to group similar resources.

For example, I have:

 app/controllers/users/users_controller.rb

I can then make my sessions controller nested inside the controllers/users director so that all resources relating to the user are grouped under the user folder.

I'm stuck though for what to do with my routes file.

When I rake routes, I can see:

 users#index {:controllers=>{:users=>"users/users"}}
                                 POST     /users(.:format)                        users#create {:controllers=>{:users=>"users/users"}}
                        new_user GET      /users/new(.:format)                    users#new {:controllers=>{:users=>"users/users"}}
                       edit_user GET      /users/:id/edit(.:format)               users#edit {:controllers=>{:users=>"users/users"}}
                            user GET      /users/:id(.:format)                    users#show {:controllers=>{:users=>"users/users"}}
                                 PATCH    /users/:id(.:format)                    users#update {:controllers=>{:users=>"users/users"}}
                                 PUT      /users/:id(.:format)                    users#update {:controllers=>{:users=>"users/users"}}
                                 DELETE   /users/:id(.:format)                    users#destroy {:controllers=>{:users=>"users/users"}}

In my routes file, I've tried a few things (set out below) - none of them work:

Rails.application.routes.draw do
  devise_for :users,
             :controllers => {
                :sessions => 'users/sessions',
                :registrations => "users/registrations",
                :omniauth_callbacks => 'users/omniauth_callbacks'
              }

  resources :identities, 
    :controllers => {
        :identities => 'users/identities'
    }


  resources :users do
  scope module: :users do
    resources :users
    end
    end 

  root 'home#index'

end

I have also tried:

resources :users,
    :controllers => {
        :users => 'users/users'
    }

Each time, I get an error that says:

ActionController::RoutingError at /users
uninitialized constant UsersController

I don't know what I need to do to get this working. I have changed each of my controllers that is nested inside the controllers/users folder with a prefix of:

 Users:: 

Can anyone see how to set this up so that I can keep my files neatly organised?

Note: I haven't created the same file directory structure in my models folder. I want to - but I'm concerned that I'm not able to figure this out for the controllers. Can anyone see what I'm doing wrong?


Solution

  • I recommend you put the actual users_controller in the base controllers directory, and only put the nested controllers inside the users directory (ie follow the same structure as the nesting).

    The alternative is to name the users_controller the way that rails is expecting ie inside the Users module:

    module Users
      class UsersController < ApplicationController
         ...
    

    and then refer to it with: Users::UsersController I always find the duplication in the name a bit cumbersome, and prefer top-level controllers to just be in the base directory.