While learning how to write tests for requests, I came across a different way of writing links in Rails. Up until this discovery I’ve used URL helpers as such:
| |
By checking the application’s routes, we can see URL helpers (1st column) and URI Patterns (3rd column).
$ rails routes -c accounts
Prefix Verb URI Pattern Controller#Action
accounts GET /accounts(.:format) accounts#index
POST /accounts(.:format) accounts#create
new_account GET /accounts/new(.:format) accounts#new
edit_account GET /accounts/:id/edit(.:format) accounts#edit
account GET /accounts/:id(.:format) accounts#show
PATCH /accounts/:id(.:format) accounts#update
PUT /accounts/:id(.:format) accounts#update
DELETE /accounts/:id(.:format) accounts#destroy
URL helpers are mapped URI patterns, but we can also use these endpoints directly. In this case, the new_account URL helper is the same as /accounts/new. So the previous link can be changed to:
| |
If a link requires an ID, we can add it through string interpolation. So the following link…
| |
…can be rewritten like this:
| |
This also applies to nested routes. Lets say we have the following in routes.rb:
| |
This block generates the following routes for the statement model:
$ rails routes -c statements
Prefix Verb URI Pattern Controller#Action
account_statements POST /accounts/:account_id/statements(.:format) statements#create
new_account_statement GET /accounts/:account_id/statements/new(.:format) statements#new
edit_account_statement GET /accounts/:account_id/statements/:id/edit(.:format) statements#edit
account_statement PATCH /accounts/:account_id/statements/:id(.:format) statements#update
PUT /accounts/:account_id/statements/:id(.:format) statements#update
If we want to create a link to edit a statement using a URL helper, we would write the following. (Notice we need to pass in two different IDs):
| |
We can rewrite the link using a URI pattern instead.
| |
Both URL helpers and URI patterns get the job done, but I enjoyed using URI patterns for familiarity. If an external application is going to communicate with a Rails API, they’ll use the same endpoints defined in URI patterns. It keeps things a bit more consistent.