What are the nested routes in Ruby on Rails?

Routing is the process of mapping incoming requests to the appropriate controller actions. It involves defining a set of routes in the application's configuration file that specify which URLs should be handled by which controller actions. These routes can also include placeholders for dynamic data, such as IDs or usernames, which can then be accessed by the controller action.

Nested routing

Nested routing allows the creation of routes that are nested within another resource's routes. This means that a resource can have multiple levels of associations, and each association can be represented by a nested URL.

Implement nested routes in Ruby on Rails

Consider a real-life scenario in which we have two resources in our application—authors and books. Each book is associated with an author, and each author can have multiple books. To set up nested routing, we can define a route for books that is nested within the route for authors. Let's implement it step by step as follows:

Note: A boilerplate application is provided below the following steps. Click the "Run" button to launch the application.

Step 1: Create the parent and nested components

Use Active Record associations to create a relationship between Book and Author models. A book belongs to a particular author, and each author can have multiple books. The following commands are used to generate the models:

rails generate scaffold Author username:string
rails generate scaffold Book content:text author:references
Create models

The first command generates a Rails scaffold for an Author model with a username attribute of string data type.

The second command generates a scaffold for a Book model, with a content attribute of text data type, and an author attribute that references the Author model.

It creates a migration file, <random_number>_create_books.rb, in the ./db/migrate/ directory containing the following code:

class CreateBooks < ActiveRecord::Migration[5.2]
def change
create_table :books do |t|
t.text :content
t.references :author, foreign_key: true
t.timestamps
end
end
end

Note: The table includes a column for an author foreign key. This key will take the form of author_id.

It also creates the following Book model file book.rb in the ./app/models/ directory:

class Book < ApplicationRecord
belongs_to :author
end
./app/models/book.rb

It specifies that the Book object belongs to the Author object using the belongs_to method, which creates an association between the two models. This means that the Book object will have the author_id attribute that references the primary key of the Author object, and that Book objects can be accessed through an associated Author object.

Step 2: Add associations for the parent model

For the parent model i.e. Author, we have to add the association manually. Go to the ./app/models/author.rb file, and add the following code to it:

has_many :books
has many association

The has_many method is used to establish a one-to-many association between the Author model and the Book model. This means that an instance of the Author model can have many associated Book instances.

The Author model will look like the following:

class Author < ApplicationRecord
has_many :books
end
./app/models/author.rb

Step 3: Add migrations and seed data

The models are ready now. Next, migrate the database and dummy data in it. Execute the following command in the terminal to run the migrations:

rails db:migrate
Rails migrations

Add some dummy data in the database. We are using the following seed data to insert data in the database in the ./db/seeds.rb file:

taylor = Author.create!(
username: "Taylor"
)
Book.create!(
[
{
content: "Red (Taylor's Version)",
author: taylor
},
{
content: "All Too Well (Taylor's Version)",
author: taylor
},
{
content: "We Are Never Ever Getting Back Together (Taylor's Version)",
author: taylor
},
{
content: "Begin Again (Taylor's Version)",
author: taylor
}
]
)
./db/seeds.rb

Run the following command in the terminal to add the seed data:

rails db:seed
Add dummy data

The command above will create an author and add multiple books that belong to that author.

Step 4: Set up nested routing

Next, set up the routes in the ./config/routes.rb file. Currently, it has the following:

Rails.application.routes.draw do
resources :books
resources :authors
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
# root "articles#index"
end
"./config/routes.rb" file before changes

The code above shows that the routes for the resources are not dependent at all. Change the code to the following to include nested routing:

Rails.application.routes.draw do
# Nested routes
resources :authors do
resources :books
end
# show books
resources :books
# Adding root path
root 'authors#index'
end
"./config/routes.rb" file after adding nested routes

The first section of the code establishes a nested route between the Author and Book resources. This means that a book resource is nested under an author resource, and its URL path includes the ID of the associated author.

The second section of the code creates standard routes for the Book resource, outside of the nested route. This means that a book can also be accessed independently of its association with an author.

The third section of the code adds a root path to the application, which means that the default URL for the application will be the index action of the AuthorsController.

Step 5: Update the nested controller

In the last step, update the BooksController to show the books that belong to some specific author. We just need to update the index and show method in the ./app/controllers/books_controller.rb file with the following code:

# Index controller
def index
if params[ :author_id]
@books = Author.find_by_id(params[:author_id]).books
else
@books = Book.all
end
end
# Show controller
def show
@book = Book.find(params[:id])
end
Books index and show controller

The first action is the index action. It checks if the :author_id parameter is present in the request URL parameters. If it is, it finds the author with the ID specified in the :author_id parameter and assigns the books associated with that author to an instance variable @books. If :author_id is not present, it simply assigns all books in the database to @books. This action is typically used to display a list of books, and if the :author_id parameter is present, it displays the books by that author.

The second action is the show action. It finds the book with the ID specified in the :id parameter and assigns it to an instance variable @book. This action is typically used to display the details of a single book.

Coding example

Look at the following code, it has implemented all of the steps mentioned above:

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
RoR application with nested routes

Note: Click on the "Run" button to execute the application. Also, click on the URL provided after "Your app can be found at:" to open the application in a new tab.

The application displays the authors on the root page. Once we click the "Show this author," it displays the information of that specific author. Now, we can append /books in the URL, it will display all of the books belonging to that author.

In this way, we can create a nested route for the books that is associated with an author. We can also append /2 at the end of the URL. The resulting URL structure might look something like this: /authors/1/books/2, where 1 is the ID of the author and 2 is the ID of the book.

By using nested routing, we can easily access all of the books associated with a particular author, and create, update and delete books in the context of that author. We can also generate URL helpers like author_book_path and new_author_book_path to easily create links to these nested routes. Overall, nested routing allows for a more intuitive and organized URL structure in our Rails application.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved