Skip to content

Instantly share code, notes, and snippets.

@clay-whitley
Last active December 21, 2015 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save clay-whitley/6336266 to your computer and use it in GitHub Desktop.
Save clay-whitley/6336266 to your computer and use it in GitHub Desktop.

#Routing in Rails

##Resources

In Sinatra applications, you may have noticed a pattern in the routes/controller actions (they are the same in Sinatra) you were creating. In Rails, the common routes of index, show, new, edit, create, update, and destroy are all contained in a "resource". You typically will want a resource for each model in your application you want to perform these actions on. For example, this would constitute a users resource:

HTTP verbPathController ActionUsed for
GET/usersindexGet a list of all users
GET/users/:idshowShow the profile of a specific user
GET/users/newnewDisplay a form to create a user
GET/users/:id/editeditDisplay a form to edit a user
POST/userscreateCreate a new user
PUT/users/:idupdateUpdate an existing user
DELETE/users/:iddestroyDelete an existing user

This resource would be created with this line of ruby in the config/routes.rb file.

resources :users

It will link the routes, with their appropriate controller actions. In this example, it will assume there is an app/controllers/users_controller.rb file, that contains the index, show, new, edit, create, update, and destroy instance methods inside of a UsersController class.

Sometimes, you don't need all the routes that the resources method will by default create for you. Let's say that the application is going to incorporate the form for creating a user into dropdowns on the main page, and so there is no need for a new route. In that case, use the only option to specify which routes you want:

resources :users, only: [:index, :show, :edit, :create, :update, :destroy]

##Helper Methods

When you create a resource, rails creates a bunch of very handy helper methods that return the path for any given route. These helper methods can be used inside the controller and views instead of having to hardcode in a url for a link.

PathHelper Method
/usersusers_path
/users/:iduser_path(:id)
/users/newnew_photo_path
/users/:id/editedit_photo_path(:id)
You can also pass an instance of a model instead of an id, and it will return the correct path for that model instance.

Also, each of these helpers corresponds with another helper, these with _url instead of _path (for example users_url) that return the ENTIRE URL including the host and port along with the path. It would return localhost:3000/users instead of /users.

##Nested Resources

When there is model association going on in an application (which is almost always), nested resources can come into play. Lets say that we want our user model from before to have multiple posts. There are has_many and belongs_to relationships setup in each model, and a migration has been created and ran. What's left is to create the routes necessary to allow a user to view all the posts from a given user, among other things. Rails offers a nifty syntax to automatically generate the routes necessary:

resources :users do
  resources :posts
end

This will create these routes:

HTTP verbPathController Action
GET/users/:user_id/postsindex
GET/users/:user_id/posts/:idshow
GET/users/:user_id/posts/newnew
GET/users/:user_id/posts/:id/editedit
POST/users/:user_id/postscreate
PUT/users/:user_id/posts/:idupdate
DELETE/users/:user_id/posts/:iddestroy

It will assume there is a PostsController class in the app/controllers/posts_controller.rb file with those actions, just like a normal resource would.

##Collection and Member routes

Sometimes, you may want to add more routes than the 7 provided by default in a resource. You either will want to define a route that will perform an action on the entire collection in the resource (all the users), or on a single member of the resource (an individual user). In order to do this, rails allows for easy implementation of additional routes on members and collections:

resources :users do
  member do
    get 'preview'
  end

  collection do
    get 'slideshow'
  end
end

This will create two additional routes. One will be /users/:id/preview and is our member route. This will map to a preview action in the UsersController. The second route will be /users/slideshow and is the collection route (since you want a slideshow of all users), and is mapped to the slideshow action in the UsersController.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment