天天看点

acts_as_taggable Plugin 使用方式

Tag 似乎是目前所有Web2.0網站所必備的功能,也有人這樣講「沒有 Tag 就不是 Web 2.0 的網站」。雖然綜觀 Web 2.0 的定義,跟 tag 似乎一點關係都沒有 XD ,不過這完全不要緊,tag 不管是不是 Web 2.0,他對於「歸類」這檔事所帶來的影響是跟「分類」一樣重大的。

Rails 上面要實踐 tag 功能最簡單的就是使用 acts_as_taggable 來做,說到這個 acts_as_taggable 可能會令人有點 confuse,他分成 Plugin 版本,跟 Gem 版本的。兩者實做方式不太一樣, Plugin 版本跟 Gem 版本最大的不同呢,就是 Plugin 版本 acts_as_taggable 他是使用兩個 table 就可以表示許多個 Model 的 tag,你不需要使用多個 table 來表示不同 Model 的 Tag ,再這一點來看,的確是一個不錯的設計,而 GEM 版本的 acts_as_taggable 你必須每個 Model 的都新增一個 table 來表示 tag。也因為設計哲學上面的不同,也有 投票來投到底那個比較好。

我們這裡先介紹 Plugin。要先注意到的,act_as_taggable plugin 是depend on Rails 1.1 以上的,所以你必須使用 Rails 1.1 以上的版本。

安裝 acts_as_taggable

script/plugin install acts_as_taggable

建立相關 table

script/generate migration add_tag_support

在 db/migrate/ 檔案裡面這樣寫

class AddTagSupport < ActiveRecord::Migration
def self.up
#Table for your Tags
create_table :tags do |t|
  t.column :name, :string
end

create_table :taggings do |t|
  t.column :tag_id, :integer
#id of tagged object
t.column :taggable_id, :integer
#type of object tagged
t.column :taggable_type, :string
end

# Index your tags/taggings
add_index :tags, :name
add_index :taggings, [:tag_id, :taggable_id, :taggable_type]
end

def self.down
drop_table :taggings
drop_table :tags
end
end      

然後打入

rake migrate

建立相關 table。

設定 Model

設定方式沒有比這個更簡單了,就是在你要下 tag 的 Model 寫入

class ModelName < ActiveRecord::Base
acts_as_taggable
end      

即可。

開始使用

下 tag

如果要對其中一個 Model 物件下 tag ,tag 內容是 'abc def ghi',代表這是一個字串,每個 tag pattern 用空白隔開。那我們就可以這樣下 tag

obj.tag_with( 'abc def ghi')

取出這個 Model 所有的 tag

如果,要取出這個 Model 物件下面的 tag,那就

obj.tags

這是一個 tag 的 array ,裡面每個東西都是一個 tag 物件,如果想要取出這個 tag array 的每個 tag name,就這樣用

obj.tags.each { |tag| puts tag.name }

即可。

尋找同一個 tag 的所有 entry

如果要搜尋這個 Model 底下所有下這個 tag 的 entry,就這樣使用

obj.find_tagged_with('abc')

他會回傳同一個 Model array,裡面是有下這個 tag 的 Model 物件。

覆蓋掉 tag

如果想用新的 tag ,就直接用 tag_with 覆蓋掉即可

obj.tag_with('new tag')

即可

刪除其中一個 tag

只想刪除掉其中一個 tag ,那就用 ActiveRecord 裡面的 destroy 即可,下面例子就是刪除 tag id 等於 1的 tag ,但是不刪除其他 tag

obj.tags.each do |tag|

tag.destroy if tag.id == 1

end

這樣即可。