Анонсирую свой новый плагин - acts_as_taggable_with_types. Суть этого плагина проста - возможность пометки объектов разными типами тэгов.

Общая абстрактная идея пометки тэгами была реализована еще DHH в плагине acts_as_taggable, а затем Jonathan Viney развил идею, создав acts_as_taggable_on_steroids. Последний и был взят за основу при создании плагина.

Итак, разные типы тэгов - для чего оно надо? Например, есть у нас такая задача: мы создаем социальную сеть, в которой пользователь должен иметь возможность в профиле указать два типа своих интересов - музыкальные предпочтения и предпочтения в кинематографе. В идеале, интересы пользователя лучше всего хранить в тэгах, однако acts_as_taggable и acts_as_taggable_on_steroids нам не позволяют хранить типы тэгов. Тут на помощь и приходит мой плагин:

class User < ActiveRecord::Base
  acts_as_taggable :music, :film
end

На выходе мы получаем методы, аналогичные tag_list и tag_list= в предыдущих плагинах: music_list, music_list=, film_list, film_list=. Первые два отвечают за список музыкальных тэгов, вторые - тэгов по фильмам. Причем сохраняются методы tag_list и tag_list=, которые позволяют работать со списком тэгов в целом, вне зависимости от типа тэгов.

@user.music_list = "Rock, Trash"
@user.film_list = "Horror, Comedy"
@user.save
@user.reload

@user.music_list # => "Rock, Trash"
@user.film_list # => "Horror, Comedy"
@user.tag_list # => "Rock, Trash, Horror, Comedy"

Поиск по меткам

Для поиска объектов по тематическим меткам, используйте методы find_by_* и find_all_by_*. Первые - для выборки одного объекта, вторые - для выборки коллекции объектов:

User.find_by_music("Rock") # => @user1

User.find_all_by_music("Rock") # => [@user1, @user2]

Для выборки по нескольким меткам одновременно, укажите метки через запятую. В этом случае будут выбраны записи, у которых встречается одна или несколько из указанных меток:

User.find_all_by_music("Rock, Trash") # => [@user1, @user2, @user3]

Для поиска с обязательным включением всех меток, используйте ключ :match_all => true:

User.find_all_by_music("Rock, Trash", :match_all => true) # => [@user3]

Для поиска по меткам вне зависимости от их типа, используйте методы find_by_tag и find_all_by_tag:

User.find_all_by_tag("Rock, Comedy") # => [@user1, @user2, @user4]

Установка

Для начала, устанавливаем сам плагин:

ruby script/plugin install \ http://dekart-plugins.googlecode.com/svn/trunk/acts_as_taggable_with_types

Затем, запускаем генератор для создания миграции с необходимыми таблицами:

ruby script/generate taggable_migration AddTaggingSupport

Ну и напоследок, запускаем сами миграции:

rake db:migrate

Баги для плагина можно постить сюда: http://code.google.com/p/dekart-plugins/issues/list

Пока что плагин без тестов, однако я надеюсь исправить это досадное упущение.