Routing

Ruby on Rails Fundamentals
Course 1 ยท Chapter 2 ยท Routing

๐Ÿ›ค๏ธ Routing

Chapter 1's generator briefly added a single route entry as a side effect. This chapter covers config/routes.rb properly โ€” and specifically the single line, resources :posts, that replaces an entire file's worth of Express route definitions with one declaration.

๐Ÿ“„ config/routes.rb

Rails.application.routes.draw do
  get "welcome/index"
  # more routes go here
end

Every route in a Rails app is declared inside this one file, inside the draw block โ€” a single source of truth, unlike Express's routes potentially spread across multiple router files mounted together (as Chapter 1's comparison showed).

โšก resources :posts โ€” Seven Routes, One Line

Rails.application.routes.draw do
  resources :posts
end

This single line generates all seven conventional RESTful routes for the Post resource. Run rails routes to see exactly what got created:

$ rails routes -c posts

    Prefix   Verb    URI Pattern              Controller#Action
     posts   GET     /posts                   posts#index
             POST    /posts                   posts#create
  new_post   GET     /posts/new               posts#new
 edit_post   GET     /posts/:id/edit          posts#edit
      post   GET     /posts/:id               posts#show
             PATCH   /posts/:id               posts#update
             PUT     /posts/:id               posts#update
             DELETE  /posts/:id               posts#destroy

Seven distinct actions, mapped to conventional URLs and HTTP verbs, generated entirely from one word: :posts. Rails infers the controller name (PostsController, from Chapter 1), the pluralization, and every URL pattern from that single symbol.

๐Ÿ“œ The Same Seven Routes โ€” Rails vs Express

One Line vs a Full File

Express (from Chapter 1's example)Rails
router.route('/').get(controller.list).post(controller.create);
router.route('/:id').get(controller.show).patch(controller.update).delete(controller.remove);
(plus new/edit routes, if the app renders server-side forms)
resources :posts

Express requires every verb/path/handler combination spelled out explicitly โ€” genuinely more visible and traceable, but genuinely more typing, and easy to have drift out of sync with REST conventions over time. Rails' single line is faster to write and impossible to get inconsistent, at the cost of needing to already know what those seven routes actually are.

๐Ÿ”— Named Route Helpers

posts_path        # => "/posts"
post_path(5)      # => "/posts/5"
new_post_path      # => "/posts/new"
edit_post_path(5) # => "/posts/5/edit"

resources :posts also generates named path helpers, visible as the Prefix column in the rails routes output above. Instead of hardcoding "/posts/#{id}/edit" as a string throughout the app โ€” the way you'd typically build a URL in Express, string-interpolating a path directly โ€” Rails gives you a real method call. Rename the route later, and every call site using the helper updates automatically; every hardcoded string wouldn't.

๐Ÿช† Nested Resources

Rails.application.routes.draw do
  resources :posts do
    resources :comments   # nested under posts
  end
end

# generates, among others:
# GET  /posts/:post_id/comments      comments#index
# POST /posts/:post_id/comments      comments#create

Nesting resources :comments inside resources :posts generates comment routes scoped under a specific post's ID โ€” the Rails equivalent of Express's router.use('/posts/:postId/comments', commentsRouter) pattern, again collapsed to a declarative block instead of manual router mounting.

๐ŸŽฏ Limiting and Customizing Routes

resources :posts, only: [:index, :show]        # just these two, nothing else
resources :posts, except: [:destroy]         # all seven except deleting

resources :posts do
  member do
    post "publish"   # POST /posts/:id/publish -- acts on ONE post
  end
  collection do
    get "drafts"    # GET  /posts/drafts     -- acts on the whole collection
  end
end
โš  Custom, non-RESTful routes need more ceremony, not less

Here's a genuine reversal of this course's usual pattern: adding one extra Express route is a single router.post(...) line, no ceremony at all. Adding a non-standard Rails route requires understanding member vs collection blocks first โ€” member for routes acting on one specific resource (needs an :id), collection for routes acting on the resource as a whole (no :id). Rails' conventions make the common case (the seven standard actions) dramatically shorter, but the moment you step outside them, you're learning Rails-specific concepts Express simply doesn't require.

๐Ÿ’ป Coding Challenges

Challenge 1: Generate and List Routes

Write the single routes.rb line for a fully RESTful articles resource, then write out, in a table or list, all seven routes you'd expect rails routes to show โ€” verb, path, and controller#action for each.

Goal: Memorize the seven standard REST routes well enough to predict them without running the command.

โ†’ Solution

Challenge 2: Convert Express Routes to Rails

Given this Express setup โ€” router.get('/products', ...), router.get('/products/:id', ...), router.post('/products', ...) only, with no update or delete routes at all โ€” write the equivalent single-line Rails routes.rb entry using only: to match exactly this reduced set of actions.

Goal: Practice recognizing when only:/except: is the right tool rather than a bare resources line.

โ†’ Solution

Challenge 3: Nested Resources Plus a Member Route

Write a routes.rb that nests resources :reviews under resources :products, and adds a custom member route, POST /products/:id/feature, that maps to a feature action on ProductsController.

Goal: Combine nested resources and a custom member route in one realistic routes file.

โ†’ Solution

๐Ÿ’Ž Where the "Magic" Actually Pays Off

Chapter 1 warned that convention over configuration can feel confusing before it clicks. Named route helpers are a clean, concrete example of where it pays off clearly: edit_post_path(@post) reads as intent ("the edit URL for this post") rather than a hardcoded, easy-to-typo string, and it stays correct automatically if the underlying URL structure ever changes. This is the kind of small, compounding ergonomic win the rest of this course will keep surfacing.

๐ŸŽฏ What's Next

Next chapter: Controllers & Actions โ€” writing the seven conventional action methods routing actually calls, working with params, and how Rails' controller layer compares to Express's request handlers.