Module ActiveRecord::Acts::Taggable::ClassMethods
In: lib/taggable.rb

This mixin provides an easy way for adding tagging capabilities (also known as folksnomy) to your active record objects. It allows you to add tags to your objects as well as search for tagged objects.

It assumes you are using a fully-normalized tagging database schema. For that, you need a table (by default, named tags) to hold all tags in your application and this table must have a primary key (normally a id int autonumber column) and a name varchar column. You must also define a model class related to this table (by default, named Tag).

All tag names will be stored in this tags table. Taggable objects should reside in their own tables, like any other object. Tagging objects is performed by the acts_as_taggable mixin using a has_and_belong_to_many relationship that is automatically created on the taggable class, and as so, a join table must exist between the tags table and the taggable object table.

The name of the join table follows the standards for rails

Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names.

The join table must be composed of the foreign keys from the tags table and the taggable object table, so for instance, if we have a tags table named tags (related to a Tag model) and a taggable photos table (related to a Photo model), there should be a join table tags_photos with int FK columns photo_id and tag_id. If you dont use a explicit full model related to the join table (through the +:join_class_name+ option), you must not add a primary key to the join table.

The acts_as_taggable adds the instance methods tag, tag_names, +tag_names= +, +tag_names<< +, +tagged_with? + for adding tags to the object and also the class method find_tagged_with method for search tagged objects.

Examples:

  class Photo < ActiveRecord::Base
    # this creates a 'tags' collection, through a has_and_belongs_to_many
    # relationship that utilizes the join table 'photos_tags'.
    acts_as_taggable :normalizer => Proc.new {|name| name.downcase}
  end

  photo = Photo.new

  # splits and adds to the tags collection
  photo.tag "wine beer alcohol"

  # don't need to split since it's an array, but replaces the tags collection
  # trailing and leading spaces are properly removed
  photo.tag [ 'wine ', ' vodka'], :clear => true

  photo.tag_names # => [ 'wine', 'vodka' ]
  # You can remove tags one at a time or in a group
  photo.tag_remove 'wine'
  photo.tag_remove 'wine beer alcohol'

  # appends new tags with a different separator
  # the 'wine' tag wont be duplicated
  photo.tag_names << 'wine, beer, alcohol', :separator => ','

  # The difference between +tag_names+ and +tags+ is that +tag_names+
  # holds an array of String objects, mapped from +tags+, while +tags+
  # holds the actual +has_and_belongs_to_many+ collection, and so, is
  # composed of +Tag+ objects.
  photo.tag_names.size # => 4
  photo.tags.size # => 4
  # Now you can clear all tags in one call
  photo.clear_tags!

  # Find photos with 'wine' OR 'whisky'
  Photo.find_tagged_with :any => [ 'wine', 'whisky' ]

  # Finds photos with 'wine' AND 'whisky' using a different separator.
  # This is also known as tag combos.
  Photo.find_tagged_with(:all => 'wine+whisky', :separator => '+'

  # Gets the top 10 tags for all photos
  Photo.tags_count :limit => 10 # => { 'beer' => 68, 'wine' => 37, 'vodka' => '22', ... }

  # Gets the tags count that are greater than 30
  Photo.tags_count :count => '> 30' # => { 'beer' => 68, 'wine' => 37 }

  # Replace allows you to find_tagged_with, remove the old tags and add the new ones
  Photo.replace_tag("beer whisky","wine vodka")
  # Display the photos returned from the tags_count call using 9 different CSS classes
  <% Photo.cloud(@photo_tags, %w(cloud1 cloud2 cloud3 cloud4 cloud5 cloud6 cloud7 cloud8 cloud9)) do |tag, cloud_class| %>
    <%= link_to(h("<#{tag}>"), tag_photos_url(:name => tag), { :class => cloud_class } ) -%>
  <% end %>

  # Display the photos returned from the tags_count call using 5 different font sizes
  <% Photo.cloud(@photo_tags, %w(x-small small medium large x-large)) do |tag, font_size| %>
    <%= link_to(h("<#{tag}>"), tag_photos_url(:name => tag), { style: => "font-size: #{font_size}" } ) -%>
  <% end %>

You can also use full join models if you want to take advantage of ActiveRecords callbacks, timestamping, inheritance and other features on the join records as well. For that, you use the +:join_class_name+ option. In this case, the join table must have a primary key.

  class Person
    # This defines a class +TagPerson+ automagically.
    acts_as_taggable :join_class_name => 'TagPerson'
  end

  # We can open the +TagPerson+ class and add features to it.
  class TagPerson
    acts_as_list :scope => :person
    belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_id'
    before_save :do_some_validation
    after_save :do_some_stats
  end

  # We can do some interesting things with it now
  person = Person.new
  person.tag "wine beer alcohol", :attributes => { :created_by_id => 1 }
  Person.find_tagged_with(:any => 'wine', :condition => "tags_people.created_by_id = 1 AND tags_people.position = 1")

Methods

Included Modules

ActiveRecord::Acts::Taggable::InstanceMethods

Public Instance methods

This method defines a has_and_belongs_to_many relationship between the target class and the tag model class. It also adds several instance methods for tagging objects of the target class, as well as a class method for searching objects that contains specific tags.

The options are:

The +:collection+ parameter receives a symbol defining the name of the tag collection method and it defaults to +:tags+.

The +:tag_class_name+ parameter receives the tag model class name and it defaults to +’Tag’+.

The +:tag_class_column_name+ parameter receives the tag model class name attribute and it defaults to +’name’+.

The +:normalizer + paramater takes a Procs. This is used to normalize all tags Simple example :normalizer => Proc.new {|name| name.capitalize}

The +:join_class_name+ parameter receives the model class name that joins the tag model and the taggable model. This automagically defines the join model class that can be opened and extended.

The remaining options are passed on to the has_and_belongs_to_many declaration. The +:join_table+ parameter is defined by default using the standard has_and_belongs_to_many behavior.

[Validate]