Yesterday we covered some basics about Routing in Rails, described what a resource actually is, and saw a few illustrations that showed some of the power behind using RESTful Rails conventions when sending and receiving requests.
Today, continuing from Obie Fernandez’ book: The Rails 3 Way, we’ll take a closer look at whats actually going on when we use Rails’ routing conventions. Remember how we were calling the same path for different REST actions yesterday? Well this next section is geared towards understanding this topic a little better.
The REST facility of Rails allows us to use the same path call for our routing purposes of multiple actions. The way we can do this is by using the same path call, but stipulating different HTTP verbs.
Here’s a quick example:
From line 2 above, we can see that the HTTP verb associated with each route created has been explicitly set, it is now clear to see how we could call
users_path in our code and receive two different HTTP responses based upon the different verbs (GET & POST) used by the route.
Rails does not force us to use RESTful conventions, we could create a route that maps to any controller action, with any method name we desire to write in our controller.
The powerful benefits of going with the RESTful conventions provided, is that we gain an advantage of perceiving our app’s communication abilities through a standardized set of controller action names and an added efficiency bonus of having a technique for creating bundles of named routes that automatically point to a specific set of actions.
If you’ve ever built a Rails app, you’ve probably utilized their automatic route generating code
resources :users, which will create 4 named routes, that map to 7 controller actions. Typing
rake routes in your console, will provide you with a list of all of your routes.
Above is an illustration snippet from my routes. The first part of the line is the helper method that is used to route the file and the second part of the line (the words in all caps) are the HTTP verbs. So from the illustration above, we can see that we could call
university_teams_path and could expect to be routed to either our
teams#create view templates depending on whichever HTTP verb is either explicitly expressed by us or implied by convention in Rails.
An example of how an HTTP verb would be implicitly expressed would be how the default HTTP verb in Rails is set to GET, another would be how our
create action automatically uses POST to PUT or commit user data from a form into our database to be used later as a representation of a resource composite.
New/Create & Edit/Update Revisited
update actions typically involve form submission.
So they really involve two requests each:
- Step 1: Display a form to GET results, either from client submission or from the database
- Step 2: Process the form input, either using the POST verb to commit a new database submission or using the PUT verb to update a current record in the database
So both the
update are closely associated with a pair of preliminary actions. ‘
new' is associated with
create and ‘
edit' is associated with
There will undoubtedly be a time when associating resources in your project becomes necessary. Some examples of this could be a program that keeps track of who sold the most treats at a bake sale. So the application calls for desserts to be associated with each user present.
Heres one way our route setup could look taking the above feature to mind:
What the second portion of the above illustration is attempting to convey is that any time we want to do something to a dessert, we will need to include which user the dessert resource belongs to. Or as The Rails 3 way puts it, we begin treating desserts as a user/dessert pair.
Once we created our nested resource of users/desserts earlier we now have paths like in the above illustration. These paths, once nested will contain the parent and descendent nested resource and provide a nested path as we see above. These nested urls give us immediate access to the user’s id through the parent resources’
In order to receive the benefits of this we must remember that when using a nested desserts resource url, to provide a user object passed in as an argument to the nested path like so:
I have been enjoying the process of getting a better grasp of Rails routing, and will be continuing this topic until I can confidently write controllers without errors from NilClass and such. If you have anything to add to this post, feel free to comment!