Skip to content

Routing

We stick to Rails defaults in terms of routing just to make working with Avo as straighforward as possible.

Avo's Engines

Avo's functionality is bundled in a few gems and most of them have their own engines. By default we mount the engines under Avo's routes using a configuration like this one.

ruby
# Your app's routes.rb
Rails.application.routes.draw do
  mount Avo::Engine, at: Avo.configuration.root_path

  # other routes
end

# Avo's routes.rb
Avo::Engine.routes.draw do
  mount Avo::DynamicFilters::Engine, at: "/avo-dynamic_filters" if defined?(Avo::DynamicFilters::Engine)
  mount Avo::Dashboards::Engine, at: "/dashboards" if defined?(Avo::Dashboards::Engine)
  mount Avo::Pro::Engine, at: "/avo-pro" if defined?(Avo::Pro::Engine)

  # other routes
end

Avo.mount_engines helper

In order to make mounting the engines easier we added the Avo.mount_engines helper which returns a block that can be run in any routing context.

ruby
# The configuration above turns into
Avo::Engine.routes.draw do
  instance_exec(&Avo.mount_engines)

  # other routes
end

Sometimes you might have more exotic use-cases so you'd like to customize those paths accordingly.

Mount Avo under a scope

INFO

The :locale scope provided is just an example. If your objective is to implement a route scope for localization within Avo, there's a detailed recipe available (including this step). Check out this guide for comprehensive instructions.

If your goal is adding another scope unrelated to localization, you're in the right place. This approach works for other types of scoped routing as well.

In this example, we'll demonstrate how to add a :locale scope to your routes.

Using a locale scope is an effective way to set the locale for your users.

Only Avo engine

On the community plan, the only requirement is to wrap the Avo engine mount within the scope.

WARNING

This will work for Avo's engine routes but won't work for any of the nested engines.

If you're using avo-pro, avo-advanced or any other Avo engine check the next section.

ruby
# config/routes.rb

Rails.application.routes.draw do
  scope ":locale" do
    mount Avo::Engine, at: Avo.configuration.root_path
  end
end

Avo engine and nested engines

Because of how Rails is mounting engines, that locale scope is not being applied to nested engines like avo-advanced, avo-pro, etc.

The fix here is to tell Avo not to mount the engines and have them mounted yourself.

ruby
# config/avo.rb

Avo.configure do |config|
  # Disable automatic engine mounting
  config.mount_avo_engines = false
end

Once automatic engine mounting is disabled, the next step is to mount the Avo engine and its nested engines within the locale scope.

ruby
# config/routes.rb

Rails.application.routes.draw do
  scope ":locale" do
    mount Avo::Engine, at: Avo.configuration.root_path
  end
end

if defined? ::Avo
  Avo::Engine.routes.draw do
    scope "(:locale)" do # Take note of the parentheses
      instance_exec(&Avo.mount_engines)
    end
  end
end

WARNING

Take note of the parentheses around the (:locale) scope when mounting the engines. These parentheses are essential to ensure proper functionality.

This will instruct Rails to add the locale scope to all Avo nested engines too.

INFO

To guarantee that the locale scope is included in the default_url_options, you must explicitly add it to the Avo configuration.

Check this documentation section for details on how to configure default_url_options setting.

Add your own routes

You may want to add your own routes inside Avo so you can access different custom actions that you might have set in the Avo resource controllers.

You can do that in your app's routes.rb file by opening up the Avo routes block and append your own.

ruby
# routes.rb
Rails.application.routes.draw do
  mount Avo::Engine, at: Avo.configuration.root_path

  # your other app routes
end

if defined? ::Avo
  Avo::Engine.routes.draw do
    # new route in new controller
    put "switch_accounts/:id", to: "switch_accounts#update", as: :switch_account

    scope :resources do
      # append a route to a resource controller
      get "courses/cities", to: "courses#cities"
    end
  end
end

# app/controllers/avo/switch_accounts_controller.rb
class Avo::SwitchAccountsController < Avo::ApplicationController
  def update
    session[:tenant_id] = params[:id]

    redirect_back fallback_location: root_path
  end
end