No matter if you are writing a component based application in RoR, or if you are just using a gem in your project, if that gem do provide their own views, there is a big probability that you will want to override the engine routes. That’s what we want to handle here.

First lets see how engines handle routes

Routes for the engine are defined just like a normal rails app, in the routes.rb file.

AcaRails::Engine.routes.draw do
  resources :users
end

In order to activate those routings in base application, it’s routes.rb file also needs to be amended:

Rails.application.routes.draw do
  ...
  mount AcaRails::Engine, at: "/aca_rails"
  ...
end

Check it in the rails application with

$ rake routes
Prefix Verb          URI Pattern                       Controller#Action
    categorias GET    /categorias(.:format)             categorias#index
               POST   /categorias(.:format)             categorias#create
 new_categoria GET    /categorias/new(.:format)         categorias#new
edit_categoria GET    /categorias/:id/edit(.:format)    categorias#edit
     categoria GET    /categorias/:id(.:format)         categorias#show
               PATCH  /categorias/:id(.:format)         categorias#update
               PUT    /categorias/:id(.:format)         categorias#update
               DELETE /categorias/:id(.:format)         categorias#destroy
          root GET    /                                 dashboards#index
     aca_rails        /aca                              AcaRails::Engine

Routes for AcaRails::Engine:
home_index GET    /home/index(.:format)               aca_rails/home#index
    locked GET    /locked(.:format)                   aca_rails/home#locked
    logout GET    /logout(.:format)                   aca_rails/sessions#destroy
     login GET    /login(.:format)                    aca_rails/sessions#new
           POST   /login(.:format)                    aca_rails/sessions#create
     users GET    /users(.:format)                    aca_rails/users#index
           POST   /users(.:format)                    aca_rails/users#create
  new_user GET    /users/new(.:format)                aca_rails/users#new
 edit_user GET    /users/:id/edit(.:format)           aca_rails/users#edit
      user GET    /users/:id(.:format)                aca_rails/users#show
           PATCH  /users/:id(.:format)                aca_rails/users#update
           PUT    /users/:id(.:format)                aca_rails/users#update
           DELETE /users/:id(.:format)                aca_rails/users#destroy

Notice how engine path is mounted under defined /aca_rails part. This allows us to have the same resources names in both main Rails application and mounted engine.
The tricky part about routes is accessing base application routing helpers in engine and vice versa.

To access the current appliction routes all helpers must prefix helpers with main_app:

<%= link_to "Home", main_app.root_path %>

To reference engine routes from main app, use the aca_rails prefix:

<%= link_to "users", aca_rails.users_path %>

If engine is not namespaced, its routing proxy prefix would be aca_rails_engine instead of aca_rails.

Tip for curious ones: main_app and aca_rails are ActionDispatch::Routing::RoutesProxy instances.

Overriding engine routes

My approach is to add the following code to the route I want to override in the engine initializer inside the main app. If the engine/gem do not provide an initializer, you can create one.

#/config/initializers/aca_rails.rb
...
AcaRails::Engine.routes.prepend do
  root to: '/dashboards#index'
end