ruby-on-railsroutesnamespaces

Rails route path helpers from inside namespaced controller


I have an app with a few top level models, all working. My layout views have a header partial, and this has the main nav links on a navbar, pretty standard stuff. Now I come to add some new functionality, and because there will be more later, I decided to encapsulate the new models and controllers in a namespace to keep the app tidy. Ok, when I come to try the first index view, it won't load. The error is No route matches {:action=>"index", :controller=>"electrical/roles", :locale=>:en} That's true, the route to "roles" does not go through the electrical namespace. The error is generated when the header partial is being evaluated. The .erb code for the link is the same as all my other views, which work. Is the path helper adding the namespace to the path because it is now being called from a view within that namespace? If so, how do I route out of the namespace? Or better still, can I tell it not to mess with my paths, and I'll explicitly tell it when I want a namespaced path?

In /app/views/layouts/_header.html.erb:

<% if current_user.has_role? :admin %>
          <li class="nav-item">
            <%= link_to t('role', scope: 'activerecord.models').pluralize,
              roles_path,
              class: ['nav-link', { active: current_page?(controller: 'roles') }],
              aria: { label: t('role', scope: 'activerecord.models').pluralize } %>
          </li>
        <% end %>

In /config/routes.rb:

    Rails.application.routes.draw do
      scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
        get 'site/home'
...
        devise_for :users
        resources :users, :only => [:show, :index]
        resources :projects
        resources :tags
        resources :users, :only => [] do
          resources :roles, :only => [:destroy]
        end
        resources :roles, :only => [:index, :new, :create]
        namespace :electrical do
          resources :cable_types
...
          resources :cables
        end
      end
    
      # Defines the root path route ("/")
      root to: 'site#home'
    end

Solution

  • The most likely culprit is current_page?(controller: 'roles') it uses the current request as context and can give somewhat unexpected results when used in the older non-resource based way.

    You can avoid this by just passing a string -current_page?(roles_path).

    See: