Feb 17

Date published: 2-17-2014

Rails version: 4.0.0

Tags

One common element used by web sites is the tag. Blogs make extensive use of them, and on this blog you can find the list of tags associated with each post and a tag cloud in the toolbar on the right to see a list of all tags and how often they are used. In this tutorial, we’re going to look at a popular gem for adding tags to a model.

Copy the template site

The first thing we need to do is copy our template site and create a new project from it. Open a terminal window and switch to the directory where the template Bootstrap site is located. Run the following commands:

$ cp -r template_bootstrap_site/ tags_tutorial
$ cd tags_tutorial/

It’s a good idea now to change the module name just like we did in this tutorial in the section titled, “Update the module information.” Make sure to commit your changes to Git before moving on.

Create the Post model and views

We’re going to let Rails create all the details for the Post model and views for us as we’re more interested in getting tags up and running. Switch to the terminal window and type in the following:

$ rails generate scaffold Post title:string body:text
$ rake db:migrate
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0068s
==  CreatePosts: migrated (0.0069s) ===========================================

With those commands, we created a Post model with all the views it needs and setup the database. Let’s modify the root path in app/config.rb to point to the index of posts:

  root 'posts#index'

Let’s update the header to add some links we’ll need to create new posts. Change app/views/layouts/_header.html.erb to this:

        <%= link_to "Posts", root_path, class: "brand" %>
        <div class="nav-collapse collapse">
          <ul class="nav">
            <li><%= link_to "New post", new_post_path %></li>
          </ul>
          <ul class="nav pull-right">
            <li><%= link_to "About", about_path %></li>
          </ul>
        </div>

Let’s also update the index page to make things look cleaner as this is where we’ll be showing the tags for each post. Change app/views/posts/index.html.erb to this:

<h1>Listing posts</h1>
<% @posts.each do |post| %>
  <div class="row">
    <div class="span12">
      <div class="post">
        <ul class="options">
          <li><%= link_to 'Edit', edit_post_path(post) %></li>
          <li><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></li>
        </ul>
        <h3><%= link_to post.title, post %></h3>
        <p><%= post.body %></p>
      </div>
    </div>
  </div>
<% end %>

We need to add a little bit to the CSS to have things show properly. Add the following to the bottom  of app/assets/stylesheets/custom.css.scss:

.post {
  margin: 10px;
  padding: 10px;
  border: 1px solid black;
}

.options {
  float: right;
  list-style-type: none;
  li {
    display: inline;
  }
}

Create some basic posts and save them so you have examples to look at on the page. This is the basic layout we need to be able to view posts, so let’s save our changes in Git. Switch to the terminal and run these commands:

$ git add .
$ git commit -m "Created Post model and views"

Adding tags

In order to add tags to our Post model, we need to first add the gem to the Gemfile. Add the following line:

gem 'acts-as-taggable-on', '3.0.1'

We need to install the gem and setup the database, so switch to the terminal window and run the following:

$ bundle install
$ rake acts_as_taggable_on_engine:install:migrations
$ rake db:migrate

First we need to add tags to our Post model. We only have to add one line to app/models/post.rb:

class Post < ActiveRecord::Base
  acts_as_taggable
end

Now we need to update our views to display the tags and our form to allow us to change the tags. In app/views/posts/index.html.erb, add this line after the post body:

<p><strong>Tags:</strong> <%= post.tag_list %></p>

In app/views/posts/show.html.erb, add the following after the post body:

<p>
  <strong>Tags:</strong>
  <%= @post.tag_list %>
</p>

That handles showing the tags in our posts, so let’s modify the form so we can edit the tags on a post. Add the following after the field for the post body in app/views/posts/_form.html.erb:

  <div class="field">
    <%= f.label :tag_list, "Tags (comma separated)" %><br />
    <%= f.text_field :tag_list %>
  </div>

We need to update the controller to recognize when we pass the tag_list to the create or update actions. Update the post_params in app/controllers/post_controller.rb:

    def post_params
      params.require(:post).permit(:title, :body, :tag_list)
    end

Now we can add tags and see them at the bottom of each of our posts. What if we want to have a tag cloud like the one on this blog? I’ll show you how to add that next.

Adding a tag cloud

There’s not much we need to do to add a tag cloud to our index page. Add the following at the top of app/views/posts/index.html.erb:

<div id="tag_cloud">
  <% tag_cloud(Post.tag_counts, %w{small medium large}) do |tag, css_class| %>
    <span class="<%= css_class %>"><%= tag %></span>
  <% end %>
</div>

Now we need some CSS for the different sizes we just specified. Add the following at the bottom of app/assets/stylesheets/custom.css.scss:

#tag_cloud {
  .small { font-size: 0.9em; }
  .medium { font-size: 1.1em; }
  .large { font-size: 1.3em; }
}

If you reload the index page, you’ll see that the tag cloud is now there with different sizes depending on how many times the tag is used. That’s all the changes we’re going to make, so let’s save our work in Git. In the terminal window, run the following:

$ git add .
$ git commit -m "Added tags to the Post model"

There is a lot more you can do with tags, so check out the documentation at:

http://github.com/mbleigh/acts-as-taggable-on

The code for this tutorial can be found at:

http://github.com/wordplay/tags_tutorial

Leave a Reply

preload preload preload