- Read Tutorial
- Watch Guide Video
This guide will walk you through how to create the show action in Rails, completely from scratch, including how to implement show page links from other pages.
In this guide, we're going to discover how to implement the show action in Rails. We've already seen this in our blog scaffold. If you open blog_controller.rb
, you'll see that the show
is just an empty method. However, it does have access to the set_blog
method because of the before_action
call. It also passes the blog instance variable to the view.
Essentially, we are going to implement the same show action for our portfolio. However, I also want to give the ability for the title to become a link. Instead of the functionality that the scaffold provided for blogs where there was a separate link to show, I want to make the portfolio title the link itself.
Creating a Plan
Start the rails server rails s
and head over to localhost:3000/portfolios
Initially, I want to make the title more of a heading, so I'll add an <h2>
or <h3>
tag. Then, I want to make the title a link that will be directed to the show page. To put this plan in motion there are a few things we need to do. First of all, we need to create a show
method inside our portfolio controller. And this method should be able to call and find the portfolio item it needs to use. Then, it needs to pass the item to a show file, and finally that file needs to render the portfolio. Additionally, and we need to make a link.
These are all things we have done in one way or another, but I like to talk myself through the process before I get started, even if I am working on a project by myself. This way I have a fresh idea of the steps I need to take.
Creating the Show Method
First, let’s create the show method in our portfolio_controller.
def show end
Now we can’t leave this empty here in this controller because we need to know which portfolio item we want to access. For now, I'm going to copy the link from the update action and paste it into my show method. Eventually we will refactor and move this code to the before_action
, so we don't have all these duplicate items.
def show @portfolio_item = Portfolio.find(params[:id]) end
So in this method we have the portfolio item and it is set to find the value of the portfolio in the URL. Just as a refresher, (params[:id])
will identify the ID and the .find
method and will do a database query based on it.
Show View
Next, we have to create a new file in our /views/portfolios
folder and it's going to be called show.html.erb
.
To verify that all of it is working, let's simply create a heading for this page. <h1>Show</h1>
Save the file and we'll navigate to a show page in the browser.
Let’s try to discern what our URL will be without running a rake routes. When we go to our list of portfolio items our URL is “localhost:3000/portfolios". Consider that to edit a record, the link we use is “localhost:3000/portfolios/5/edit”. From this we know that to show a particular portfolio item we need know what the id is. It makes sense, following that convention, that our URL for the show page should be “localhost:3000/portfolios/5". Let’s hit refresh and see what we get
So, our guess is right! Though it's not rendering any data on the screen, the display let’s us know we have a valid URL because we didn’t get an error message. For example, if I removed the letter "s" put "/portfolio/5", in the URL, I will get an error message because that is not a valid route. Hopefully, you can begin to see the logic behind it that process. As “/portfolio/new” will take us to the new form, ”/portfolios/5/edit" will take us to a specific edit page, and “/portfolios/5” should take us to the show page for the portfolio with an id of 5. Therefore, passing the ID will take us to the page of that distinct record.
In reference to data flow, we started with the route that had the ID in it, and it got redirected to the show action. The presence of the instance variable @portfolio_item
means we have access to the record associated with a particular ID.
Go to show.html.erb
, and we'll see what's available inside of our variable. We will use embedded ruby and the .inspect
method.
<h1>Show</h1> <%= @portfolio_item.inspect %>
If you refresh the browser, you'll see we have a portfolio with an id of 5 and all of it’s parameters listed out.
Planning the Show Page
Let's plan out what we want to display on our show page. Over in our index.html.erb
view, we had an iterator. We looped through all the records and displayed each of them on the page. Now our show page is different because it is not a collection. Though each item may have multiple attributes and data elements, it doesn't have multiple portfolio items. So, we're not going to iterate. Instead we're simply going to print out each attribute.
In order to protect myself from potential bugs from misspelling, I’m going to open the schema.rb
file which will give us access to our attributes. Use the view < layout tool in sublime to split your screen for easier access
Back in my portfolio/show.html.erb
file, I'm going to put my title @portfolio_item.title
inside of an <h1>
tag. For right now I am going to use an emphasis tag <em>
for the subtitle @portfolio_item.subtitle
. Eventually we will replace this with our own custom styles, but for now this will make the subtitle appear in italics.
If you're wondering why we are getting that auto complete action, sublime is really intuitive in that if you have another file open, it will recognize those attributes and auto-complete the item for you. That's another reason why I like to keep the schema file open, as it makes it faster to type.
For the body attribute, @portfolio_item.body
I'm going to put that in a paragraph tag <p>
.
The last item I want to add is the image, and I want to place it above the other items. For the index page we used a thumbnail. For this page I want to use the main_image, which is the larger one. I am going to use an image tag, and because this is ruby I can call it using @portfolio_item.main_image
. The complete code is:
<%= image_tag @portfolio_item.main_image %> <h1><%= @portfolio_item.title %></h1> <em><%= @portfolio_item.subtitle %></em> <p><%= @portfolio_item.body %></p>
Save and refresh and you should see that it is working.
We have our main image followed by our title, sub title and body. That is fantastic!
Creating our Link
The next thing to do is to add a link so we can get to the show page. The easiest way is to open our index.html.erb
file and make the portfolio_item.title
a link. We're going to use the link_to
method for this.
- <p><%= portfolio_item.title %></p> + <p><%= link_to portfolio_item.title, %></p>
Notice in our edit link <%= link_to "Edit", edit_portfolio_path(portfolio_item.id) %>
we used the word "Edit", for our display. However, here for the title, we’re using a dynamic item portfolio_item.title
instead.
Next we need the path. You can get a little bit of a hint of what the path should be by looking at the edit link again. You might think you need to use 'show' as a part of the path, however with Rails, you do not need to include that. The path is just going to be portfolio_path
. But, like edit, we need to pass in the ID.
- <p><%= link_to portfolio_item.title, %></p> + <p><%= link_to portfolio_item.title, portfolio_path(portfolio_item.id) %></p>
Save your file. Now if you refresh the browser, you'll see the links for each of the items.
When you click on the title of any item, it'll take you to the show page of that item.
There is one shortcut we can do. I can delete the word "id" from both the show and edit links because Rails knows that we're going to pass an ID. Ultimately, the code can be
<h1>Portfolio Items</h1> <%= link_to "Create New Item", new_portfolio_url %> <% @portfolio_items.each do |portfolio_item| %> <p><%= link_to portfolio_item.title, portfolio_path(portfolio_item) %></p> <p><%= portfolio_item.subtitle %></p> <p><%= portfolio_item.body %></p> <%= image_tag portfolio_item.thumb_image unless portfolio_item.thumb_image.nil? %> <%= link_to "Edit", edit_portfolio_path(portfolio_item) %> <% end %>
If you refresh the page, you'll see that everything is still working.
One of my policies, which is quite prevalent in the Rails community as well, is that when you type less code, the chances for error is greatly reduced.
With all of this done, we now have the full function of creating, editing and showing items.
Lastly, let's upload files to our GitHub branch. Run a git status
and you will see we changed the portfolio controller, as well as the index and show files. We will add everything with a git add .
Next we will commit, git commit -m ‘Implemented show functionality for portfolio module’
. We will finish this with git push origin portfolio-feature
One note: I'm showing you the code for pushing to GitHub in the video because many students have requested that I should do so. It may be repetitive, but it's still good to know the commands I use to manage the Git process.
The next thing we will implement is the destroy action. We will get to that in the next guide.