Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A rails tagging gem implementing flickr's machine tags + maybe more (semantic tags)

branch: master

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 generators
Octocat-spinner-32 lib
Octocat-spinner-32 test
Octocat-spinner-32 .gemspec
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .travis.yml
Octocat-spinner-32 CHANGELOG.rdoc
Octocat-spinner-32 Gemfile
Octocat-spinner-32 LICENSE.txt
Octocat-spinner-32 README.rdoc
Octocat-spinner-32 Rakefile
Octocat-spinner-32 init.rb


This plugin implements Flickr's machine tags as explained here while still maintaining standard tagging behavior.

Basically, a machine tag has a namespace, a predicate and a value in the format


This allows for more precise tagging as tags can have unlimited contexts provided by combinations of namespaces and predicates. These unlimited contexts also make machine tags ripe for modeling relationships between objects. Read the HasMachineTags::TagMethods class documentation for a more thorough explanation.

A demo app using this plugin is here. This gem should run on all major Ruby versions and work with Rails 2.3.x and up.


Install as a gem

$ gem install has_machine_tags

# with bundler: add in Gemfile
gem 'has_machine_tags'

# without bundler: add in config/environment.rb
config.gem "has_machine_tags"

Or as a plugin

$ script/plugin install git://

Migrate your database from Rails root:

$ script/generate has_machine_tags_migration
$ rake db:migrate


Setup a model to use has_machine_tags

class Url < ActiveRecord::Base

Let's create some urls with machine tags!

url = Url.create(:name=>"",

url2 = Url.create(:name=>"",
  :tag_list=>'gem:type=tagging, gem:user=giraffesoft')

url3 = Url.create(:name=>"",

url.tag_list # => ["gem:type=tagging", "flickr"]

url.tags # => [<Tag name:"gem:type=tagging">, <Tag name:"flickr">]

Let's query them:

# Query urls tagged as a gem having type tagging
Url.tagged_with 'gem:type=tagging'  # => [url, url2] from above

# Non-machine tags work of course
Url.tagged_with 'flickr'  # => [url] from above

# tagged_with() is a named_scope so do your sweet chaining

Nothing interesting so far. We could've done the same with normal tagging.

But when we start with wildcard machine tag syntax, machine tags become more valuable:

# Query urls tagged as gems (namespace = 'gem')
Url.tagged_with 'gem:'  # => [url, url2, url3] from above

# Query urls tagged as having a user, regardless of namespace and value (predicate = 'user')
Url.tagged_with 'user='  # => [url2] from above

# Query urls tagged as gems having a user ( namespace ='gem' AND predicate = 'user')
Url.tagged_with 'gem:user'  # => [url2] from above

# Query urls tagged as having a tagging value, regardless of namespace and predicate (value = 'tagging')
Url.tagged_with '=tagging'  # => [url, url2] from above

More details on machine tag syntax can be found in the Tag class.

More Usage

The wildcard machine tag syntax can also be used to fetch tags:

# Tags that are gems
Tag.machine_tags 'gem:' # => [<Tag name:"gem:type=tagging">, <Tag name:"gem:user=giraffesoft">]

# Tags that have a user predicate
Tag.machine_tags 'user=' # => [<Tag name:"gem:user=giraffesoft">]

Of course you can do the standard tag_list manipulation:

url.tag_list = "comma, delimited"
url.tag_list # =>['comma', 'delimited']

url.tag_list = ['or', 'an', 'array']
url.tag_list # =>['or', 'an' 'array']

#Add a tag
url.tag_list << 'another_tag'
url.tag_list # => ["gem:type=tagging", "flickr", "another_tag']

#Delete a tag
url.tag_list # => ["gem:type=tagging", "flickr"]


This is an experiment in progress so the api is subject to change.

Since machine tags require special characters to implement its goodness, these characters are off limit unless used in the machine tag context:

'.', ':' , '*' , '=' , ','


  • Add a match_all option to tagged_with().

  • More helper methods ie for showing relations between namespaces, predicates + values

  • Possible add support for other ORM's ie DataMapper.

  • Play friendly with other tagging plugins as needed.


Please report them on github.


Thanks goes to Flickr for popularizing this tagging model. Thanks also goes to the acts-as-taggable-on plugin for their finder code and the is_taggable plugin for demonstrating sane testing for a Rails plugin.

Something went wrong with that request. Please try again.