How to Override the Rails Resources Routes for the Show Action
This guide examines how to override the default route path for the resources method in a Ruby on Rails application for the show action.​
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

This guide examines how to override the default route path for the resources method in a Ruby on Rails application for the show action.​

In the last guide, we talked about how we can create custom routes for our pages controller. This is helpful, but I also want to show how you can create custom routes for resources. So in this guide we will discover how you can override the default values provided by resources.

If you go to the terminal and type rake routes you'll be able to see the standard routes.

large

Now, I want to look at the portfolio routes. If you observe, the route for portfolios#show, you'll see that it has the word “portfolios" followed by the ID. I’m not an adherent of this format because this is a plural word for a single item being displayed. Therefore, I want to use the singular "portfolio" followed by the ID. Though it may seem like a small change, it's something I personally like to do.

Except

To implement this we need to go back to our routes.rb file, I'm going to use something called except. Except allows me to use the default resource routes for all the actions except the ones I specify. Since except expects an array, we will pass in show as an argument. This is going to be an array that's a symbol [:show]:

- resources :portfolios
+ resources :portfolios, except: [:show]

This indicates to the system, use all the resource routes except for the show action. Now, I need to create my custom route for show action. We will start with get 'portfolio/:id' . Rails knows when you use the colon : that we are passing in an ID, so it is expecting a parameter.

get 'portfolio/:id', 

Next we use to: followed by our mapping ’portfolios#show'.

get 'portfolio/:id', to: 'portfolios#show'

We are mapping the data so that when we get an id right after the path of ‘portfolio’, the system will pass it to the show method exactly as it did before we delegated a new route. Your file should look like this:

Rails.application.routes.draw do
  resources :portfolios, except: [:show]
  get 'portfolio/:id', to: 'portfolios#show'

  get 'about-me', to: 'pages#about'
  get 'contact', to: 'pages#contact'

  resources :blogs

  root to: 'pages#home'
end

If you go to the terminal and run rake routes again you should be able to see portfolio/:id mapped to the show action.

large

Let's start the rails server and see if it works. It looks like it should, I’m just not sure about the ‘Portfolio’ prefix method, but let's just see what happens. Go to "localhost:3000/portfolios", and that still works. However, if we click on one of the portfolio item's title's we get an error message No route matches.

large

So, clearly the system is expect the word "portfolios". To debug, go back to the portfolios page, right-click on a title, then choose the "Inspect" option. If you look at the bottom pane, you'll see that it's still trying to go to portfolios/7. Let's discover why.

If you go to our views/portfolio/index.hrml.erb page, you'll see that the code where we've linked our title is redirected to portfolio_path, which seems like the path we would want, but this actually isn’t giving us the action we want. So, we will have to implement our own custom route.

As is a Method

Go to routes.rb. We will add another method to our get ‘porfolio/:id’ route, This method is called as:. It will take a string as an argument, and we will use ’portfolio_show’ for that string.

- get 'portfolio/:id', to: 'portfolios#show'
+ get 'portfolio/:id', to: 'portfolios#show', as: 'portfolio_show'

Let’s try and determine if this works. Go to your terminal and run rake routes.

Notice how the prefix for portfolio#show is now portfolio_show That's what we want. Now we need to update our view. Go to your portfolios/index.html.erb file and replace portfolio_path with portfolio_show_path.

- <p><%= link_to portfolio_item.title, portfolio_path(portfolio_item) %></p>
+ <p><%= link_to portfolio_item.title, portfolio_show_path(portfolio_item) %></p>

Let's save the file and refresh the browser and see if this works.

large

Now the URL is using the singular “portfolio" followed by the id. This looks much better. Also, by going through this process, we've learned how to override the default resources value, and also, how to add our own custom route method.

Rails is really flexible, so you can override the default value anywhere you want. You can do that for blogs too, but I have a little treat for us, as we're going to learn about something called friendly IDs using our blog routes. In fact, that's what we're going to get into in the next guide.

Last, let's add files to our GitHub branch. Let’s do a git status. This shows that we changed our index and routes files. That correct so we can go ahead and use git add . followed by git commit -m ‘Customized portfolio routes’ and finally git push origin portfolio-feature. We have been on this branch for awhile, but I think that this feature is coming along nicely. For our final step head over to Pivotal Tracker and check off our task.

Resources