Skip to content
Blazing fast ActiveRecord library to create tags using ElasticSearch
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Blazing fast Ruby alternative to acts-as-taggable-on and other similar gems. Instead of million of records in the database it uses powerful ElasticSearch, which gives a very fast and scalable solution with a search capabilities of ElasticSearch.


All you need is to add in your Gemfile the follwing line.

gem 'tagliani'

And run bundle install command.


  • ActiveRecord
  • redis-client
  • elasticsearch

To run this gem it is required to have ActiveRecord.


In your rails app config/initializers create tagliani.rb with the following content

Tagliani.configure do |config|
  config.elasticsearch.url = "http://localhost:9200" # URL of your ElasticSearch service, by default set to this endpoint
  config.elasticsearch.index = "tagliani_#{Rails.env}" # Index name
  config.elasticsearch.refresh = true # false by default
  config.elasticsearch.log = true # false by default
  config.redis.url = "redis://localhost:6379/tagliani" # By default set to this endpoint
  config.redis.queue = "tagliani" # By default set to this queue name
  config.redis.length = 200 # By default set to 200. It is a queue length per bulk that is going to be sent to ElasticSearch


Let's say inside the Rails application you have a model with a name "Hashtag", that represents all the tags attached to the model "Tweet".

class Hashtag < ActiveRecord::Base
  include Tagliani::Concerns::Search

class Tweet < ActiveRecord::Base
  taggable tag_kls: "Hashtag"

tag_kls is optional. By default it set to Tag model

To attach the tag simply execute:

tweet = Tweet.create(body: "Follow @rrubyist on Twitter")
tweet.tags.add(name: '#followme')

To list the attached tags you can run:


It will return you an array of Hashtag objects attached to the Tweet model.

[#<Hashtag id: 2, name: "#followme", sticker: "default">]

If you want to search for all tweets attached to the Hashtag model with a name #followme you can use public search method defined in class.

You don't have to specify tag_kls, unless you have multiple models that act as Tag model { tag_name: ['#followme'], tag_kls: ['Hashtag'] }

Tag name represents the name field of the Hashtag model.

[#<Tweet id: 3, body: "Tweet #0">, #<Tweet id: 4, body: "Tweet #1">, 
#<Tweet id: 5, body: "Tweet #2">, #<Tweet id: 6, body: "Follow @rrubyist on Twitter">]

More search

In fact, you can do so much more with it. You are in power of using all the abilities of ElasticSearch. For example, you can search using a *. You can write pro* and match all tags that contain this part of the word at the beginning of the name tag. { tag_name: ["pro*"] })
=> [#<Tag id: 3, name: "professor", sticker: "default">, #<Tag id: 4, name: "professional", sticker: "default">]

Asyncronous bulk index

For a non-blocking processes you can enable option to index jobs in background queue.

class Artist < ActiveRecord::Base
  has_many :albums
  tagliani async: true

To index in bulks, simply execute:


Inherit tags from models

You can specify the models you want to inherit tags from by adding an option :inherit with a list of models in the taggable method.

class Album < ActiveRecord::Base
  has_many :songs
  belongs_to :artist
  belongs_to :producer

  taggable inherit: %i[artist producer]


Bug reports and pull requests are welcome on GitHub at This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.


The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Tagliani project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

You can’t perform that action at this time.