Anıl Pak
Anıl Pak's Blog

Anıl Pak's Blog

Rails Acts as Taggable On gem

Why and How to use it?

Anıl Pak's photo
Anıl Pak
·Apr 3, 2021·

3 min read

Rails Acts as Taggable On gem

taggable.png Using tags creates a better user experience for your clients. Especially If they don't know what they are looking for, It can help them to easily find it. Also, they may stay on your page for longer.

If you are new to Ruby on Rails, creating a join table in your database and understanding many to many relationships can be a bit tricky. When I was working on my recent project instead of creating a join table, I applied taggable gem.

It's always good to remember that If you are using taggable you won't have a tags column in your database. To make it clearer, I am sharing how to use it and how easy it is to implement it in your project.

I built a travel website for my family business and I used the taggable gem to help our clients to find their next destination more easily and to make the Front-end fancier. Let's start implementing it!

Let's start with adding a taggable gem to our gem file.

Gemfile

gem 'acts-as-taggable-on', '~> 6.0'

Do not forget bundle install and generate the migration after adding gem. Next step adding tags to the model you are going to use.

#app/models/tour.rb
class Tour < ApplicationRecord
  has_many :bookings, dependent: :destroy
  has_many :reviews, :through => :bookings, dependent: :destroy
  has_many_attached :photos

 acts_as_taggable_on :tags
end

Now we can move to the controller and update it regarding taggable.

#app/controllers/tours_controller.rb
  def index
    if params[:tag].present?
      @tours = Tour.tagged_with(params[:tag])
    else
      @tours = Tour.all
    end
  end

and also permit the tag params inside the controller.

private

def tour_params
      params.require(:tour).permit(:tag_list, :title, :description, :duration, :group_size, :price, photos: [])
end

Now we can move to the Front-End;

<div class="container">
  <h1 id="anchor-tag">Explore Our Top Destinations</h1>
  <div class="text-center mb-5">
    <% ActsAsTaggableOn::Tag.all.each do |tag| %>
      <%= link_to tag, tours_path(tag: tag.name, anchor: "anchor-tag" ), class: "btn-taggable d-inline-block mb-3 #{"active-tag" if params[:tag] == tag.name}" %>
    <% end %>
  </div>
</div>

Finding related tours based on tags, You should use the find_related_tags method given by the gem on the show page for each tour.

  def show
    @tours = Tour.all
    @tour = Tour.find(params[:id])
    @related_tours = @tour.find_related_tags
  end

In my project, I created all my tours from seed.rb file. Let's create a tour together.

#db/seed.rb
tour_1 = Tour.create(title: "Cappadocia Hot Air Balloon Ride", description: "Hot Air Balloon Ride", duration: "2 hours", group_size: "10-16 People", price: 189)
tour_1.tag_list = "Cappadocia"
tour_1.save

Basically, that's all! I used taggable gem in both the Tour and Article model. After I created multiple tags for both models, all the tags I created for both models displayed on my tour show page. You can easily avoid using the reject method and you can display only tags you want to show on a certain page. For example; I want to display all the tags except the one that has index number four,

    <% ActsAsTaggableOn::Tag.all.reject.with_index { |el, index| index == 4 }.each do |tag| %>
      <%= link_to tag, tours_path(tag: tag.name, anchor: "anchor-tag" ), class: "btn-taggable d-inline-block mb-3 #{"active-tag" if params[:tag] == tag.name}" %>
    <% end %>

Note -> When the user selects the tag, the page will automatically go up to the top of the page, which is so annoying for the user. To keep the user in the same section, you should give an anchor tag and an id. When users select any of the tags they will stay in the same section.

Result

For More Information

taggabblegem.PNG

 
Share this