Every year I decide to write a she coded post, it's on a work day where I'm convinced I know very little about some thing and get stuck on it. I even wouldn't be surprised if it was the same thing-- routing in Rails.
Today I was trying to set up routes properly for a new controller. Here's some basic information about routing that I revisited in the process of figuring out what my issue was:
Resource routing
I always get a little mixed up on what a resource even is, so my quick way of thinking about it now is that the resource is the object we're controlling with our controller. The resource is the object we're Create/Read/Update/Delete
-ing.
Using the resources
keyword in the routes file is a quick way to route seven different HTTP methods, as in the following example from the docs:
resources :photos
This one line maps the following different routes to the photos controller:
Path | Controller | Method |
---|---|---|
/photos/new | photos | new |
/photos | photos | create |
/photos/:id | photos | show |
/photos/:id/edit | photos | edit |
/photos/:id | photos | update |
/photos/:id | photos | delete |
This table is available in the Rails docs that also includes the HTTP verbs if you're interested.
If you don't want any of the default methods you can use the only
keyword to generate routes for the controller methods you want. An example:
resources :photos, only: [:show]
If you have a singular resource you want to route, you can define it like this:
get 'profile', to: 'users#show' # this uses the controller#action syntax which you'll see a lot in Rails
Nested Resources vs Namespaces
Namespaces are something you want to use when you have controllers that exist under some logical grouping (Ex. Admin::
). These would get nested in your routes file in a namespace block like so:
namespace :admin do
# YOUR RESOURCES HERE
end
And they'd generate paths along the lines of /admin/YOUR_RESOURCE
. There are lots of fun ways you can customize this behavior using scopes so that the path looks more to your liking, and you can check out the docs for more.
Nested resources on the other hand are when you have objects that are associated with each other.
For example, if you had these two classes:
class Photo < ApplicationRecord
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :photo
end
Each with their respective controllers.
You could use nested routes to define routes for both of these controllers. In addition to the photos routes we talked about earlier, you'd get the routes for comments as well.
resources :photos do
resources :comments
end
For example one of the paths this would generate is /:photo_id/comments
which would map to the comments#index
controller#action.
Member vs Collection
Both of these blocks let us extend beyond those seven default routes that resources
generates for us. The big thing to remember here is member
is for when we want to specify an id for a specific resource object that we're performing the action on, and collection
is for when we want to call a method for the collection of resources as a whole and don't need to specify the id of a specific resource.
Both of these blocks have a single line syntax using on:
you can use if you have a one off method you'd like to route in this way.
Once again, the Rails docs are the best place to go to read more.
What was the problem?
Oh, there was more than one file containing routes (it's a big Rails application) and I was editing the wrong (but very similarly named) one 🙃.
Thanks for reading, as always.
Top comments (0)