Acts As Taggable On Steroids

[b][color=gray]参考着mephisto写blog程序,第一次看到[].collect(&:name)的写法,别笑我……书上没见过,代码又写得少,结果就是这样。
=============================================
答案在这里:[url]http://www.infoq.com/cn/articles/ruby-open-classes-monkeypatching[/url]
[/color][/b]

主要记录一下acts_as_taggable_on_steroids的用法。
[b][url]http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids[/url][/b]

首先,[b]安装[/b]这个插件到项目中:
ruby script/plugin install git://github.com/jviney/acts_as_taggable_on_steroids.git

[b]使用[/b]
接着,执行:
ruby script/generate acts_as_taggable_on_steroids_migration
会生成如下migration代码:
class ActsAsTaggableMigration < ActiveRecord::Migration

def self.up
create_table :tags do |t|
t.column :name, :string
end

create_table :taggings do |t|
t.column :tag_id, :integer
t.column :taggable_id, :integer

# You should make sure that the column created is
# long enough to store the required class names.
t.column :taggable_type, :string
t.column :created_at, :datetime
end
add_index :taggings, :tag_id
add_index :taggings, [:taggable_id, :taggable_type]
end

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

这里建了两个表,tag表和taggings表。taggings表看着像是个多对多的连接表,另外多了个taggable_type字段,估计是要做成不同类型的taggable对象都能通用的吧。
然后……只要在需要tag的类里边加一句acts_as_taggalbe的调用就可以了……自己不用插件瞎搞了大半天的东东,两三个命令加一句代码解决了。嗯?居然没有Tag类,估计隐藏在插件内部了。grep一下:
grep 'class Tag' ./ -r
果然……
[quote]./vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb:class Tag < ActiveRecord::Base[/quote]

继续贴代码。
class Article < ArticleContent
acts_as_taggable
belongs_to :user
has_many :comments
end


ruby script/console

#加上acts_as_taggable的类会自动加上tag_list的accessor
a=Article.new
#writer只需要逗号分隔的字符串作参数
a.tag_list="tag1,tag2,tag3"
#reader返回的是字符串数组。
a.tag_list #=> ["tag1","tag2","tag3"]
a.save
#可以用taggable类(这里即Article类)的类方法find_tagged_with来查找
#拥有某个指定tag的所有Article对象
articles=Article.find_tagged_with 'tag1' #=> [#<Article id: 2, title: nil, hits: nil, user_id: nil, created_at: "2010-01-19 17:10:05", updated_at: "2010-01-19 17:10:05", content: nil, type: "Article">]

#By default, find_tagged_with will find objects that have any of the given tags.
#To find only objects that are tagged with all the given tags, use match_all.
articles=Article.find_tagged_with 'tag1,asdf' #=> [#<Article id: 2, title: nil, hits: nil, user_id: nil, created_at: "2010-01-19 17:10:05", updated_at: "2010-01-19 17:10:05", content: nil, type: "Article">]
articles=Article.find_tagged_with 'tag1,asdf', :match_all=>true #=> []
articles=Article.find_tagged_with 'tag1,tag2', :match_all=>true #=> [#<Article id: 2, title: nil, hits: nil, user_id: nil, created_at: "2010-01-19 17:10:05", updated_at: "2010-01-19 17:10:05", content: nil, type: "Article">]


还有个tag_counts方法,可以这样调用:
Article.tag_counts

还可以这样:
user.articles.tag_counts


[b]标签云[/b](云到底是什么概念?)可以这么玩:
首先把一个Helper的Module include到ApplicationHelper中
  module ApplicationHelper
include TagsHelper
end

示例:
Controller:
  class PostController < ApplicationController
def tag_cloud
@tags = Post.tag_counts
end
end

View:
  <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
<%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
<% end %>

CSS:

.css1 { font-size: 1.0em; }
.css2 { font-size: 1.2em; }
.css3 { font-size: 1.4em; }
.css4 { font-size: 1.6em; }

[b]缓存[/b]
为了减少查询数据库的次数,可以给taggable对象增加一个字段,用来存放所有的标签列表(以字符串形式),字段名为cached_tag_list:
  class CachePostTagList < ActiveRecord::Migration
def self.up
add_column :posts, :cached_tag_list, :string
end
end

  class Post < ActiveRecord::Base
acts_as_taggable

# cached_tag_list是默认的字段名,也可以换一个名字:
# set_cached_tag_list_column_name "my_caching_column_name"
end

最后是[b]分隔符[/b]
默认的分隔符是半角逗号“,”,这个值也可以改,比如说改成空格:
TagList.delimiter = " "
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值