In config/routes.rb, which seven routes does resources :photos generate, with their HTTP verbs, paths, controller actions and named helpers?
answer
- four helper names, seven actions
- collection vs member paths
- new drawn before :id
- update answers PATCH and PUT
- each route takes (.:format)
basics
~10 sresources :photos draws index and create on /photos, new on /photos/new, and show, edit, update and destroy on /photos/:id, all handled by PhotosController, with helpers photos_path, new_photo_path, edit_photo_path and photo_path.
solid answer
~30 sOne `resources :photos` line maps seven actions of `PhotosController`. The collection path `/photos` takes `GET` for `index` and `POST` for `create`; `GET /photos/new` is `new`; the member path `/photos/:id` takes `GET` for `show`, `PATCH` and `PUT` for `update`, and `DELETE` for `destroy`; `GET /photos/:id/edit` is `edit`. Only four helper names come out of it: `photos_path` (index and create), `new_photo_path`, `edit_photo_path(photo)` and `photo_path(photo)` (show, update, destroy), each with a `_url` twin. Every path also accepts an optional `(.:format)`, and the id arrives as `params[:id]`.
code
ruby · 4 lines# config/routes.rb
Rails.application.routes.draw do
resources :photos
endgo deeper
Recite the seven rows: verb, path, action and helper. Group them into collection routes, member routes and the new form, and remember that only four helper names exist.
Explain why helpers are per path rather than per verb, why new must be drawn before the :id route, and what the optional format segment adds to every path.
Use the table to reason about requests that miss: a trimmed new falling through to show, an undefined action answering 404, and what API-only mode removes.
Treat the seven actions as a team contract that generators, forms and reviewers rely on, and push back on routes that bypass it without a reason.
## What one resources line does In a Rails application the router reads `config/routes.rb` from top to bottom and builds a table of **routes**: each pairs an HTTP verb and a path pattern with a `controller#action` and, usually, a **named route** that generates the URL back. Writing those lines one by one is possible (`get "photos/:id", to: "photos#show"`), but the everyday form is a **resourceful route**: ```ruby Rails.application.routes.draw do resources :photos end ``` For a photography-portfolio site that single line draws every route the photo pages need, all mapped to `PhotosController`. ## The table interviewers expect | Verb | Path | Action | Helper | |---|---|---|---| | GET | `/photos` | `index` | `photos_path` | | GET | `/photos/new` | `new` | `new_photo_path` | | POST | `/photos` | `create` | `photos_path` | | GET | `/photos/:id` | `show` | `photo_path(photo)` | | GET | `/photos/:id/edit` | `edit` | `edit_photo_path(photo)` | | PATCH / PUT | `/photos/:id` | `update` | `photo_path(photo)` | | DELETE | `/photos/:id` | `destroy` | `photo_path(photo)` | Read it as two groups: - **Collection routes** act on the set of photos and carry no id: `index` lists them, `create` adds one. - **Member routes** act on one photo and carry `:id`: `show`, `edit`, `update` and `destroy`. - `new` is the odd one out: a form page for a photo that does not exist yet, so it sits under the collection path with a fixed `new` segment. The `:id` segment arrives in the controller as `params[:id]`, a string. The router does not check that a record exists; it only matches the pattern. ## Helpers: four names, two flavours The seven actions share **four route names**, because a name belongs to a path, not to a verb: 1. `photos` covers `GET` and `POST /photos`. 2. `new_photo` covers `GET /photos/new`. 3. `edit_photo` covers `GET /photos/:id/edit`. 4. `photo` covers `GET`, `PATCH`, `PUT` and `DELETE /photos/:id`. Each name defines a `_path` helper (a relative path such as `/photos/7`) and a `_url` helper (the full URL with host). The verb is chosen by whatever sends the request, such as a form or a `button_to`, not by the helper. ## PATCH and PUT both reach update Rails draws **two routes** for `update`: one for `PATCH` and one for `PUT`, both on `/photos/:id`. `bin/rails routes` lists them on separate lines. Rails' own forms submit `PATCH` for an existing record, so `PUT` is there for clients that send a full replacement; both land in the same action, and the controller cannot tell from the route which one arrived unless it reads `request.method`. ## Details that come up as follow-ups - **Order matters.** The router tries routes in the order they were drawn, and `resources` draws `new` before `show`, so `/photos/new` reaches `new` instead of `show` with `params[:id] == "new"`. - **Format segment.** Every path ends in an optional `(.:format)`, so `/photos/7.json` reaches `show` with `params[:format] == "json"`. - **API-only apps.** With `config.api_only = true`, `resources` drops `new` and `edit`, because a JSON client needs no HTML form pages; five actions remain. - **Missing actions.** The routes exist whether or not the controller defines the methods. A request to a route whose action is neither defined nor backed by a template raises `AbstractController::ActionNotFound`, which answers 404. ## Mistakes interviewers listen for | Belief | What `resources :photos` actually draws | |---|---| | Every action has its own helper | Four names: `photos`, `new_photo`, `edit_photo`, `photo` | | `POST /photos/:id` updates | `POST` exists only on `/photos`, for `create` | | Update is `PUT` only | Both `PATCH` and `PUT` reach `update` | | The controller is `PhotoController` | It is the plural `PhotosController` | | The router checks the record exists | It matches the pattern; the action's lookup decides | ## Why the convention matters The seven actions are a contract shared by the router, the controllers, the form helpers and other developers. Anyone who knows the table can read `resources :photos` and know which URLs exist, which method handles each, and which helper builds each link, without opening the controller. Interviewers ask for the table because so much of the framework assumes it: - `form_with` picks `POST` or `PATCH` according to whether the record is new, and expects these routes to exist. - `redirect_to @photo` resolves through the `photo` route name. - The scaffold generator writes a controller with exactly these seven methods. A route table that departs from the seven actions is not wrong, but every departure is something the next developer has to look up.
- Why does GET /photos/new not reach show with params[:id] set to "new"?Routes match in the order they are drawn, and `resources` draws the `new` route before the member routes. `/photos/new` therefore matches `GET /photos/new` first. If `new` is removed with `only:` or `except:`, the same request falls through to `GET /photos/:id` and reaches `show` with `params[:id] == "new"`.
- What changes in the table when the app was generated with --api?With `config.api_only = true`, `resources :photos` draws five actions: `index`, `create`, `show`, `update` and `destroy`. The `new` and `edit` routes, and their `new_photo_path` and `edit_photo_path` helpers, are not drawn, because they exist only to serve HTML forms.
saying these in an interview costs you the question
- resources :photos defines a separate helper name for every one of the seven actions
- Updates must be sent with PUT because Rails only routes PUT to update
- POST /photos/:id is the route that updates a photo
- The router checks that the photo exists before calling show
- resources :photos routes to a PhotoController class