iThome online | iThome Blog | iThome周刊訂閱

載入中...

twtw

IT邦初學者
9級

[RoR] 簡單加入 Tag, Tagging 標籤功能

當第一次使用 del.icio.us 社會性書籤 時,分享書籤並不稀奇,神奇的是透過 Tag 標籤的功能,更能發現到別人在相同議題上的搜集,而更多人的 Tag 同一個項目,就更看到該項目的價值。所以就夢想著,自己也可在自己所建置的系統中,有 Tagging 的功能。然而在 RoR 中可以很省力地建立此功能。

本篇目標是先建立不區分 User 的標籤系統,了解一下如何建置,之後再建立可區分哪些 User 建立哪些標籤的系統。



收到書籤:發佈到twitter      
分享時間:2008-10-10 10:33:12

▼ ADVERTISEMENT ▼

分享內容(
4

安裝 be_taggable
RoR 中有關 tag 相關的 plugins 也有好幾種,在此採用 be_taggable ,並且以第三日 [RoR] 簡單完成 CRUD 的動作 中的最簡單的 Blog 裡的 Article 做為標籤的對象:

cd /home/ironman/test
./script/plugin install http://railers.rubyforge.org/svn/plugins/trunk/be_taggable
script/generate be_taggable_tables Article
# 其中會產生 db/migrate/20081009xxxx_add_be_taggable.rb ,裡面會有些錯誤,修改:
# 將 add_column articles, :tags_cache, :string, :default => "--- []" 這一行改為
add_column :articles, :tags_cache, :string, :default => "--- []"
# 將 remove_column articles, :tags_cache 改為
remove_column :articles, :tags_cache
# 再執行 才不會因上述的問題 而出現錯誤訊息
rake db:migrate

Console 端操作測試 Tag 功能
在要被 tag 的 Model 中,加入設定,在此編輯 app/models/article.rb,加入 be_taggable 的字樣:
class Article < ActiveRecord::Base
be_taggable
before_save :generate_permalink
...

執行 ./script/console
# 以第一篇文來加標籤
>> a = Article.find(1)
=> #<Article id: 1, title: "Save the Cheerleader, Save the World", body: "Save the Cheerleader, Save the World\r\nSave the Chee...", created_at: "2008-09-11 00:00:00", updated_at: "2008-10-02 08:28:40", permalink: "save-the-cheerleader-save-the-world", tags_cache: "--- []">
>> a.tag('影集,英雄,Heroes')
=> true
# 再以另一篇文章來加標籤
>> b=Article.find(11)
=> #<Article id: 11, title: "救啦啦隊長,救世界", body: "一群平凡如你我的人們 卻擁有特殊基?...", created_at: "2008-10-02 20:12:27", updated_at: "2008-10-02 20:12:27", permalink: "jiu-la-la-dui-chang-jiu-shi-jie", tags_cache: "--- []">
>> b.tag('Heroes,英雄')
=> true
# 第11篇文,已把剛標籤的內容放在 tags_cache 之中
>> b.tags_cache
=> "--- \n- heroes\n- !binary |\n  6Iux6ZuE\n\n"
# 尋找有以 '英雄' 為標籤的文章
>> Article.find_tagged_with('英雄')
=> [#<Article id: 1, title: "Save the Cheerleader, Save the World", body: "Save the Cheerleader, Save the World\r\nSave the Chee...", created_at: "2008-09-11 00:00:00", updated_at: "2008-10-09 16:41:11", permalink: "Save-the-Cheerleader-Save-the-World", tags_cache: "--- \n- heroes\n- !binary |\n  5b2x6ZuG\n\n- !binary |\n ...">, #<Article id: 11, title: "救啦啦隊長,救世界", body: "一群平凡如你我的人們 卻擁有特殊基?...", created_at: "2008-10-02 20:12:27", updated_at: "2008-10-09 16:45:34", permalink: "jiu-la-la-dui-chang-jiu-shi-jie", tags_cache: "--- \n- heroes\n- !binary |\n  6Iux6ZuE\n\n">]

在各文章中顯示已有的標籤
經過上述的測試,接著試著把各文章的標籤,可在 views 中顯示出來:
# 在 app/views/blog/show.html.erb 加入:
標籤:
<% for tag in YAML::load(@article.tags_cache) -%>
  <%= tag -%>
<% end -%>


YAML 的語法也使用在 RoR 裡面的所有 *.yml 的檔中,可利用 find ./ -name \*.yml 發現到用 YAML 的檔案;而將 tag 寫到 tags_cache 之中,也減少了許多對資料庫的存取動作。

加入編輯標籤的界面
編輯 app/views/articles/edit.html.erb 加入:
    標籤:<br />
<% darray = YAML::load(@article.tags_cache) -%>
<%= text_field_tag 'tag', darray.join(' ') -%>

編輯 app/controllers/articles_controller.rb 在 def update 中加入:
    @article.tag(params[:tag].split(' ').join(','))

即可在頁面增減標籤了。由於 be_taggalbe 加入各標籤,是要以','作為區分,而大部人下標籤不習慣去加那個逗號,所以頁面以空個來隔開各標籤的方式來呈獻及輸入,但實際在 controller 的處理裡,把空格改為逗號來寫入標籤。

同樣地在 new 的 view 中加入 tag 的欄位供,也在 controller 中的 create 加入 上述寫入標籤的語法,就提供在寫新文章時,可直接輸入 標籤。

提供標籤的連結
只有顯示標籤還不夠,還要把有相同標籤的文章列出來的功能,希望能夠 http://SITE/tag/英雄 就可列出相關的文章。
在 app/controllers/blog_controller.rb 多加:
  def findtag
   @title = "以 #{params[:id]} 為標籤的文章"
   @prearticles = Article.find_tagged_with(params[:id])
   @articles = @prearticles.paginate :per_page => 5, :page => params[:page]
        render :template => 'blog/index'
  end
#
# 並在 config/routes.rb 加入:
map.tagged_articles 'tag/:id', :controller => 'blog', :action => 'findtag'
可以有上述所提網址的呈獻

上述第2行,多加個標題來辨識
上述第3行,先把有該標籤的文章成一陣列,再交給下一行的 will_paginate 處理顯示
上述第5行,與 blog index 共用同一個 template。

再改一下 app/views/blog/index.html.erb 顯示的方式:
<!-- 是否有 @title 的變數來決定秀出什麼字樣出來 -->
<% if @title.nil? %>
<h2>文章列表</h2>
<% else %>
<h2><%= @title -%></h2>
<% end %>
...
<!-- 將標籤連結加入 -->
<div class="tag">
標籤:
<% for tag in YAML::load(article.tags_cache) -%>
  <%= link_to(tag, tagged_articles_path(tag)) -%>
<% end -%>
</div>

這樣就可以有一個不分使用者的簡單標籤系統功能。

參考資料:http://railers.rubyforge.org/be_taggable/

[RoR] 簡單加入 Tag, Tagging 標籤功能

目前沒有資料

回應

請填寫您的回應,長度限為1,000個字,回應不計點數,也不限使用次數



 

檢舉違規

違規事項:

*補充檢舉理由(可省略),字數不可超過100字

推薦

推薦理由:


*給回答者的鼓勵(可不填),字數不可超過100字

▼ ADVERTISEMENT ▼

熱門標籤

 ccna代考   cisco   crystal   exchange   iscsi   it   java   javascript   linux   m-power   mail   msnlib   msnp15   msnsdk   msn機器人   mysql   nas   oracle   outlook   pmi   pmp   report   sap   server   smartquery   sql   vista   vpn   web   windows   xp   二三事   倍力   倍力資訊   免費軟體   國際專案管理師   報表   專案管理   有話大聲說   活動   省錢   網路   網路儲存   網路管理   網頁設計   資安   資訊安全   防毒軟體   2003   2008