Icaro
Icaro

Reputation: 107

correct way to use routes.rb namespace rails?

I'm trying to create a back-end area to my application, so I've created a folder named backend and backend_controller.rb inside it. I need the folder because the backend area will have multiple folders, so it's better-separated from my others.

my routes.rb looks like:

namespace :backend do
    get 'index'
end

my backend_controller.rb:

class BackendController < ApplicationController
  def index
  end
end

But in this mode Rails will search for my backend_controller.rb inside the controllers folder, not in controller>backend. I've tried many variations, and I get routing errors.

So what is correct way to do that? To set the path /backend to index action instead of /backend/index?

Thanks


What i've done:
based on all answers, principally the one from Cyril DD

I've created the backend_controller.rb on the app/controller folder and in the sub-folder app/controller/backend i created the static_pages_controller.rb and all files looks like this:

app/controllers/backend_controller.rb:

class BackendController < ApplicationController
end

app/controller/backend/static_pages_contter.rb:

class Backend::StaticPagesController < BackendController
    def dashboard
    end
end

routes.rb:

namespace :backend do
    resource :static_pages, path: '', only: [] do
        root to:'static_pages#dashboard'
end

this works fine, but cause i'm newbie on rails i must ask. This is a good or a conventional way to do that? to administrate the permissions which user can see on the backend i use the backend_controller.rb right? and at last wy i must use resource: instead just get ''

Upvotes: 1

Views: 2882

Answers (2)

Cyril Duchon-Doris
Cyril Duchon-Doris

Reputation: 14029

Answering your question

Alright, namespace :something is a shorthand for scope 'something', module: 'something', as: 'something'

Now your declaration is very ambiguous, because you don't specify a controller. Typical declarations look like (assume you have a controller controllers/backend/some_resources_controller.rb and you want to generate default routes)

namespace :backend do
  resources :some_resources
end

Now what you did

namespace :backend
  get 'index'
end

is really ambiguous and I'm not surprised it doesn't do what you want. Basically you just tell rails to "look inside subfolder 'backend' and define the route 'index'". oO ? Which file/controller are we even talking about ?

What is your backend_controller.rb supposed to do ? Is it some kind of Control Panel ? Dashboard ? If so you're probably gonna have a lot of non-CRUD actions, but anyways you should go for the following syntax

namespace :backend
  # Below line of code will auto-generate the `index` for /backend/backend_controller
  resource :backend, only: [:index], path: '' do # we need " path: '' " otherwise we'll have https://xxx/backend/backend/dashboard
    # If you have non-CRUD actions, put them here !
    get 'dashboard' # https://xxx/backend/dashboard
    ...
  end
  # However, this will create URLs like "https://xxx/backend/dashboard", etc.
  # If you want to redirect https://xxx/backend/ to your backend_controller#index, use root
  root to: 'backend#index' # https://xxx/backend/
end

Last thing as mentionned by other guys, when you namespace a file like your Backend_controller inside /backend/ subfolder, you must rename the class like (/controllers/backend/backend_controller)

class Backend::BackendController < ApplicationController

Remark : if you only have like one or two controller actions, instead of using the resource method, you can declare singular resources

namespace :backend do root to: 'backend#dashboard' get 'dashboard', to: 'backend#dashboard' # singular resource end


An Example of what you may actually really want to do...

I'm not sure you are clear yourself about what you want to do. As an example, here is my architecture

Files

/controllers/application_controller.rb
/controllers/backend_controller.rb
/controllers/backend/static_pages_controller.rb
/controllers/backend/***.rb

The class /controllers/backend_controller.rb will not serve any action, but will override ApplicationController to tune it for backend access (but maybe you don't need to do so)

class BackendController < ApplicationController
  # Do you need to change user_access method ? Or any other backend-wide config ?
  # If so put this config here, otherwise leave empty
end

Now for every file that goes in the /backend/ subfolder, I inherit the backend_controller

class Backend::StaticPagesController < BackendController
  def index
  end

  # Note : if your index is some kind of dashboard, instead I would declare
  def dashboard
  end
end

class Backend::SomeResourcesController < BackendController
  ...
end

Routes

namespace :backend do
  root to 'static_pages#index' # https://xxxx/backend/
  resource :static_pages, only: [:index], path: '' # https://xxxx/backend/index
  resources :some_resources
end

If you choose the dashboard solution in your controller, write instead :

namespace :backend do
  root to: static_pages#dashboard # https://xxxx/backend/
  resource :static_pages, path: '', only: [] do
    get 'dashboard' # https://xxxx/backend/dashboard
  end
  resources :some_resources
end

Upvotes: 1

thedanotto
thedanotto

Reputation: 7327

Then it's simply

# routes.rb 
Rails.application.routes.draw do
  namespace :backend, shallow: true do
    resource :backend, path:''
  end
end

Then in your app/controllers/backend/backend_controller.rb, it'd look like this.

class Backend::BackendController < ApplicationController
  def index
  end
end

When I use rake routes it shows

          Prefix Verb   URI Pattern                 Controller#Action
backend_backends GET    /backend(.:format)          backend/backends#index

Hope this helps.

Upvotes: 1

Related Questions