Rails 5 Basics : Show Article

Objective

  • Learn how to display a selected article in the article show page.

Steps

Step 1

Add the 'Show' link to each article in the index page. The hyperlink text will be 'Show'.

<%= link_to 'Show', ? %>

When the user clicks the 'Show' link we need to go the articles controller, show action. We will retrieve the record from the database and display it in the view. What should be the url helper?

You can view the output of rake routes to find the url helper to use in the view. In this case we know the resource end point. We go from the right most column to the left most column and find the url helper under the Prefix column.

      Prefix Verb   URI Pattern                  Controller#Action
    articles GET    /articles(.:format)          articles#index
             POST   /articles(.:format)          articles#create
 new_article GET    /articles/new(.:format)      articles#new
edit_article GET    /articles/:id/edit(.:format) articles#edit
     article GET    /articles/:id(.:format)      articles#show
             PATCH  /articles/:id(.:format)      articles#update
             PUT    /articles/:id(.:format)      articles#update
             DELETE /articles/:id(.:format)      articles#destroy

So, we now have :

<%= link_to 'Show', article_path %>

Step 2

Go to Rails console and type:

>   app.article_path
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"articles"} missing required keys: [:id]

Rails does not recognize the article_path.

Step 3

Look at the output of rake routes command. You can see in the URI pattern column the :id variable for primary key.

article GET    /articles/:id(.:format)      articles#show

So we need to pass the id as the parameter as shown below:

<%= link_to 'Show', article_path(article.id) %>

Rails recognizes article path when an id is passed in as the parameter to the url helper method.

<a href="/articles/1">Show</a>

You can see the generated string is the same as the URI pattern in the output of the rake routes command.

We can simplify it even further by letting Rails call the id method for us by just passing the article object.

Step 4

Since Rails automatically calls the id method of the ActiveRecord we can simplify it as follows:

<%= link_to 'Show', article_path(article) %>

Step 5

Rails has optimized this even further so you can do :

<%= link_to 'Show', article %>

Let's now see how Rails makes this magic happen.

> a = Article.first
  Article Load (0.2ms)  SELECT  "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT 1
 => #<Article id: 1, title: "test first", description: "first row", created_at: "2015-11-27 03:52:06", updated_at: "2015-11-29 20:41:16"> 

Retrieving first article from database in Rails console.

 > app.article_path(a.id)
 => "/articles/1" 
 > app.article_path(a)
 => "/articles/1" 

Experimenting in Rails console to check the generated URI for a given article resource. Rails internally uses the polymorphic_path method that takes an argument to generate the url.

Step 6

The app/views/articles/index.html.erb looks as shown below:

<h1>Listing Articles</h1>

<% @articles.each do |article| %>

    <%= article.title %> : 

    <%= article.description %> 

    <%= link_to 'Edit', edit_article_path(article) %>
    <%= link_to 'Show', article_path(article) %>

    <br/>

<% end %>
<br/>
<%= link_to 'New Article', new_article_path %>

Step 7

Reload the articles index page http://localhost:3000/articles. You will see the show link.

Step 8

If you view the page source for articles index page, you will see the hyperlink for 'Show' with the URI pattern '/articles/1'. Since this is a hyperlink the browser will use the http verb GET when the user clicks on show.

In the rails server log you will see the GET request for the resource '/articles/1'. In this case the value of :id is 1. Rails will automatically populate the params hash with :id as the key and the value as the primary key of the record which in this case is 1. We can retrieve the value of the primary key from the params hash and load the record from the database.

Started GET "/articles/1" for ::1 at 2015-12-03 08:04:21 -0800

Server log is another friend.

Step 9

If you click on the 'Show' link you will get the 'Unknown action' error.

AbstractController::ActionNotFound (The action 'show' could not be found for ArticlesController):

As we saw in the previous step, we can get the primary key from the params hash. So, define the show action in the articles controller as follows:

def show
  @article = Article.find(params[:id])
end

We already know the instance variable @article will be made available in the view.

Step 10

If you click the 'Show' link, you will get the error:

No template found for ArticlesController#show, rendering head :no_content

We need a view to display the selected article. Let's define app/views/show.html.erb with the following content:

<p>
  <%= @article.title %><br>
</p>

<p>
  <%= @article.description %><br>
</p>

Since the @article variable was initialized in the show action, we can retrieve the values of the columns for this particular record and display it in the view. Now the 'Show' link will work.

Summary

In this lesson we saw how to display a selected article in the show page. In the next lesson we will see how to delete a given record from the database.


Related Articles


Software Compatibility Best Practices

I spoke to some of the most talented and experienced software developers. I have created a guide that is filled with valuable insights and actionable ideas to boost developer productivity.

You will gain a better understanding of what's working well for other developers and how they address the software compatibility problems.

Get the Guide Now