Featured image for TWIL blog post on Rails Routing with a focus on Shallow Nested Resources - insights for Ruby and Rails developers.

Dive into the latest installment of TWIL, where we serve up crisp micro-lessons for the software development enthusiast. This week, Katie gives us a lesson on Rails Routing: Shallow Nested Resources. Grasp the elegance of Rails' ability to simplify resourceful routing, trimming unnecessary nested path segments for a cleaner and more efficient coding experience in Ruby on Rails. Join us and fortify your coding toolbox with these insightful tidbits from the field.

Rails Routing: Shallow Nested Resources

Normally, when you’re creating nested resource routes in Rails, you’d set them up like:

resources :posts do
  resources :comments
end

The resulting routes would be:

post_comments     GET       /posts/:post_id/comments(.:format)
post_comments     POST      /posts/:post_id/comments(.:format)
new_post_comment  GET       /posts/:post_id/comments/new(.:format)
edit_post_comment GET       /posts/:post_id/comments/:id/edit(.:format)
post_comment      GET       /posts/:post_id/comments/:id(.:format)
post_comment      PATCH/PUT /posts/:post_id/comments/:id(.:format)
post_comment      DELETE    /posts/:post_id/comments/:id(.:format)

This is fine, but once you have the record’s id, you very likely won’t need the id of its parent resource as well (you could as easily find the record by its own id and retrieve its parent’s id from it directly). This also causes ballooning of path and URL helper names and argument lists, e.g.,

post_comment_path(comment.post_id, comment.id) vs comment_path(comment_id).

This becomes particularly onerous for deeper nesting levels, e.g., something like:

author_post_comment_path(comment.post.author_id, comment.post_id, comment.id)

where all the identifying keys are available via the comment itself, and thus just the comment id.

To set up those routes that should only need the record’s id without parent nesting, you’d need to do:

resources :posts do
  resources :comments, except: [:show, :edit, :update, :destroy]
end
resources :comments, only: [:show, :edit, :update, :destroy]

Resulting routes/names:

post_comments    GET       /posts/:post_id/comments(.:format)
post_comments    POST      /posts/:post_id/comments(.:format)
new_post_comment GET       /posts/:post_id/comments/new(.:format)
edit_comment     GET       /comments/:id/edit(.:format)
comment          GET       /comments/:id(.:format)
comment          PATCH/PUT /comments/:id(.:format)
comment          DELETE    /comments/:id(.:format)

This is a lot of extra… extra, especially for a repeated pattern and especially especially with deeper nesting.

A Better Way

…which, of course, Rails has had since at least Rails 2, but which I somehow never, ever knew.

The :shallow option for resources does exactly what you’d want here.

resources :posts, shallow: true do
  resources :comments
end

Resulting routes/names:

post_comments    GET       /posts/:post_id/comments(.:format)
post_comments    POST      /posts/:post_id/comments(.:format)
new_post_comment GET       /posts/:post_id/comments/new(.:format)
edit_comment     GET       /comments/:id/edit(.:format)
comment          GET       /comments/:id(.:format)
comment          PATCH/PUT /comments/:id(.:format)
comment          DELETE    /comments/:id(.:format)

This works for deeper nesting levels as well and can be overridden per child resource by setting shallow: false if desired.

Resources

  • Rails
Katie Linero's profile picture
Katie Linero

Senior Software Engineer

Related Posts

Dark monitoring dashboard showing an agent platform overview with real-time metrics including 2.4k requests per second, 47 concurrent AI agents, service health indicators for orchestrator and LLM gateway components, a throughput and latency time-series chart, and a streaming event log with tool calls and error traces.
February 24, 2026 • Frank Valcarcel

AI Agent Platforms Compared: From Enterprise to Self-Hosted

Your team built an AI agent. It works in a demo. Now someone asks: where does it actually run? A new category of product has emerged to solve this: agent platforms. Think of them as fleet management software for AI agents. This post compares the major options and how to choose.

Illustration of a small, determined knight in weathered medieval armor and a bucket helmet, wearing a tattered red cape, striding across barren cracked earth with sword drawn, surrounded by a swirling cloud of scattered wooden alphabet letters representing Token Guard, a GitHub Action that monitors and guards against token context bloat in AI coding agent workflows by counting the tokens in LLM instruction files committed to repositories."
February 10, 2026 • Frank Valcarcel

Token Guard: Keeping Your Agent Context Lean in CI

Token Guard is a GitHub Action that counts tokens in your agent context files and enforces limits in CI. Here’s why we check agent context into our repos, and why keeping it lean matters for team collaboration.

Let's work together

Tell us about your project and how Cuttlesoft can help. Schedule a consultation with one of our experts today.

Contact Us