Skip to content
Dave Strus edited this page Jul 15, 2015 · 1 revision

We haven't yet added a show page for posts. We've gotten away with it until now, because we've dealt primarily with links, which just send us to an external site anyway. But you may have noticed that clicking a text post's title opens /posts in a new tab, which isn't particularly helpful. Clicking a text post should take us to a page where we can see the full post, including the body.

Our resource route will suffice to define a route for posts/:id. Now we need to add the show action to PostsController. It doesn't need to do anything but find the post with the given ID and assign it to an instance variable.

app/controllers/posts_controller.rb

  def show
    @post = Post.find params[:id]
  end

We don't yet have a view for posts#show, so let's create one: app/views/posts/show.html/erb.

We can mark up the post much like we did on index, with the additional markup for body (which we'll show only for text posts). It isn't in a list this time, so we'll use an article element instead of an li. We'll put the body inside a section.

<article class="post">
  <div class="title"><a href="<%= @post.link %>"><%= @post.title %></a></div>
  <div class="tagline" title="<%= @post.created_at %>">submitted <%= time_ago_in_words @post.created_at %> ago</div>
  <% if @post.text? -%>
    <section class="body"><%= @post.body %></section>
  <% end -%>
</article>

Because our markup is a bit different than on index, we'll need some new CSS rules. Add the following to the end of your stylesheet:

app/assets/stylesheets/style.scss

article {
  .title {
    font-size: 16px;
    a:link, a:hover, a:active {
      color: blue;
    }
    a:visited {
      color: #551a8b;
    }
  }
  .tagline {
    color: #888;
    font-size: x-small;
  }
  section.body {
    border: 1px solid #3498db;
    border-radius: 7px;
    margin: 15px 0;
    padding: 5px 5px;
    background-color: #fafafa;
    max-width: 60em;
    overflow: auto;
    font-size: small;
  }
}

Use the Rails console to get the ID of a text post, then visit /posts/:id, where :id is the ID of a text post. You should see the details of your post, including the body text.

Now we need to update posts#index to send us here for any post of type text.

LAB

On posts#index, clicking on a post title should do the following:

  • For text posts, link to the show page for that post.
  • For link posts, link to the url identified by Post#link.

SOLUTION

Rather than cluttering up our view with an if-else, let's create a helper.

app/helpers/application_helper.rb

  def post_link(post)
    return post.link if post.link?
    return post_path(post) if post.text?
  end

Then we can just make a tiny change in the view.

app/views/posts/index.html.erb

    <div class="title"><%= link_to post.title, post_link(post) %></div>

Try click on some text posts and some links. Do they work as expected? If so, let's commit our changes. I'll spare you the lecture about git diff and all that.

$ git add .
$ git commit -m "Add posts/show page."

Now we have the "CR" portion of "CRUD" handled. Before long, we'll knock out the other parts.

But first, let's do some refactoring!