Acts as Taggable On Tutorial with Rails 5
For more posts in this series, check out my tutorial on Devise Authentication with Rails 5.
Acts as Taggable On is one of my favorite underrated (and awkwardly named) Rails gems. There’s almost always the need to search or organize objects in a Rails application and using tags simplifies the process so much. It also saves developers new to Rails from writing out monstrous Active Record queries. Acts-as-taggable-on is a true work horse, it’s been around since 2010 and has over 8 million downloads to date. Here is a quick getting started guide on using it.
What are tags and why do we use them?
- Tags help users find related information — they allow you to group one or several instances of a model together without having to create a separate category table.
- Tags help when users are not sure what they are looking for — for example, think of Amazon and its related products. Sometimes people who buy toothpaste will also buy tooth brushes. But your site will be more powerful if it can tag the items and suggest things like face wash or body cream.
- Tags allow for a broader ‘category’ label without having to make a standalone table or parent-child-relationship — This means that you can connect several tables without a million foreign keys.
- Therefore, tags help visitors remain on the site for longer — You want this, because $$$.
- There is no ‘tags’ column in the database table
- Tags acts as a ‘virtual column’ — it lives in its own table
- Find the full documentation here: https://github.com/mbleigh/acts-as-taggable-on/
How to use the Acts As Taggable Gem
Install the gem
#add the gem to your gemfile
gem 'acts-as-taggable-on', '~> 6.0' #must be this version for Rails5
#install with bundler
#generate the migrations to create taggings in the db
Create the model you are going to tag
rails g scaffold Restaurant name:string description:string
#NOTE: there is no tags column for the restaurants table
#add this line to app/models/restaurant.rb
Use Case 1: I want to add tags to my model in the backend
restaurant = Restaurant.new(name: “Lost Heaven”, description: "Yunnan food in the heart of the former french concession", tag_list: [“Yunnan”, “Spicy”, “Good Cocktails”])
#add or remove tags
#return all of the tags of a given restaurant
#return all of the instances of a class with a specific tag
Use Case 2: As a user, I want to be able to tag a model with a specific tag, then search for all of the restaurants by their tag
Step 1. Add the tags to permitted params in the controller
params.require(:restaurant).permit(:name, :description, :tag_list)
Step 2. Add the tags to the form of the site
<%= f.input :tag_list %>
Step 3. Search by tag filters
@restaurants = Restaurant.tagged_with(params[:tag])
@restaurants = Restaurant.all
get '/tagged', to: "restaurants#tagged", as: :tagged
<% @restaurants.each do |r| %>
<h2><%= r.name %></h2>
<p><% r.tag_list.each do |tag| %>
<%= link_to tag, tagged_path(tag: tag) %>
<% end %></p>
<% end %>
Use Case 3: As a user, I want to be able to find related restaurants based on their tags
@restaurant = Restaurant.find(params[:id])
@related_restaurants = @restaurant.find_related_tags
<h1><%= @restaurant.name %></h1>
<% @related_restaurants.each do |r| %>
<li><%= r.name %></li>
<% end %>
Useful Acts_As_Taggable Methods
#returns most and least used tags
#force all tags to be saved as lowercase
ActsAsTaggableOn.force_lowercase = true
#add tags separated by comma (default), can change to space or others
ActsAsTaggableOn.delimiter = ','
Acts As Favoritor — https://github.com/jonhue/acts_as_favoritor
Acts As Votable (Likable) — https://github.com/ryanto/acts_as_votable
Do you guys find this a useful gem? Are there any other use cases of acts-as-taggable-on that I missed? Let me know below!