A simple implementation for tagging system with postgres array. So, this gem works only on postgres.
Add this line to your application's Gemfile:
gem 'acts-as-taggable-array-on'
And then execute:
bundle
To use it, you need to have an array column to act as taggable.
class CreateUser < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :tags, array: true, default: '{}'
t.timestamps
end
add_index :users, :tags, using: 'gin'
end
end
and bundle:
rake db:migrate
then
class User < ActiveRecord::Base
acts_as_taggable_array_on :tags
end
@user = User.new(:name => "Bobby")
acts_as_taggable_array_on defines 4 scope and 2 class methods as below.
- with_any_#{tag_name}
- with_all_#{tag_name}
- without_any_#{tag_name}
- without_all_#{tag_name}
- all_#{tag_name}
- #{tag_name}_cloud
Set, add and remove
#set
@user.tags = ["awesome", "slick"]
@user.tags = '{awesome,slick}'
#add
@user.tags += ["awesome"]
@user.tags += ["awesome", "slick"]
#remove
@user.tags -= ["awesome"]
@user.tags -= ["awesome", "slick"]
class User < ActiveRecord::Base
acts_as_taggable_array_on :tags
scope :by_join_date, ->{order("created_at DESC")}
end
# Find a user with all of the tags
User.with_all_tags("awesome, slick")
User.with_all_tags(["awesome", "slick"])
# Find a user with any of the tags
User.with_any_tags("awesome, slick")
User.with_any_tags(["awesome", "slick"])
# Find a user without all of the tags
User.without_all_tags("awesome, slick")
User.without_all_tags(["awesome", "slick"])
# Find a user without any of the tags
User.without_any_tags("awesome, slick")
User.without_any_tags(["awesome", "slick"])
# Chain with the other scopes
User.with_any_tags("awesome").without_any_tags("slick").by_join_date.paginate(:page => params[:page], :per_page => 20)
Calculation to count for each tags is supported. Currently, it does not care its order.
User.tags_cloud
# [['awesome' => 1], ['slick' => 2]]
Tag cloud calculation uses subquery internally. To add scopes to the query, use block.
User.tags_cloud { where name: ['ken', 'tom'] }
To handle the result tags named 'tag' and 'count', prepend scopes.
User.where('tag like ?', 'aws%').limit(10).order('count desc').tags_cloud { where name: ['ken', 'tom'] }
Can get all tags easily.
User.all_tags
# ['awesome', 'slick']
As the same to tag cloud calculation, you can use block to add scopes to the query.
User.all_tags { where name: ['ken', 'tom'] }
To handle the result tags named 'tag', prepend scopes.
User.where('tag like ?', 'aws%').all_tags { where name: ['ken', 'tom'] }
- Fork it ( http://github.com/tmiyamon/acts-as-taggable-array-on/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request