(旧) kano-e no memo

こっちは更新してません

acts_as_taggable_on_steroids


区切り文字の指定について、間違ってたので修正しました。
Tag.delimiterでなくて、TagList.delimiterです。
tkskkcさん、ご指摘ありがとうございます。

なんでこんな間違いしたのかなーと思って調べたのですが、Tag.delimiterは古いバージョンでの書き方で、[26 August 2006]時点でTagList.delimiterに置き換えられたようです。
参考:acts_as_taggable_on_steroids/CHANGELOG
これ書いた時、古い記述を参考にしてたうえに、自分でよく確かめもしなかったのが原因でした。
反省。

前々から、acts_as_taggableを試そうと思いつつ、なかなか機会がなかったんですが(最近SQLにエネルギー傾け気味だったし)、今日ようやく試しました。
と、言いつつ。
調べたらrailsでタグを実装するpluginも色々あるらしい?
http://railsblog.yujis.jp/articles/2007/05/17/rails%E3%81%A7%E7%B0%A1%E5%8D%98%E3%81%AB%E3%82%BF%E3%82%B0%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%92%E4%BD%9C%E3%82%8B-acts_as_taggable_redux
acts_as_taggable_on_steroidsとacts_as_taggable_reduxで、それぞれちょっと違うらしい。
とりあえず。
http://blog.tkmr.org/tatsuya/show/306-rails-plugin-acts-as-taggableを読んで参考にしまくりつつ、on_steroidsの方を試すことに。

ruby script/plugin install 
http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids/
script/generate migration add_tag_support

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

そしたらmigrate

rake db:migrate

これで、準備完了?
実際にどうやって使うの?ってことで、http://wiki.rubyonrails.org/rails/pages/ActsAsTaggablePluginHowtoを確認。

試しに例の通りにBookというモデルをつくって、そこに適用させてみることに。

class Book < ActiveRecord::Base
  acts_as_taggable
end

BookControllerはscaffoldでさくっと作った。
とりあえず、フォームにタグ入力部分を追加する。

_form.rhtmlの一番下に、こっそりつけくわえる。

<%= text_field 'item', 'tag_list' %>

で、createの、

@book = Book.new(params[:book])
if @book.save

のところを

@book = Book.new(params[:book])
@book.tag_with(params[:tag_list])
if @book.save

と、いうふうにしてみた。
そしたら、なぜだかエラー。tag_withなんてメソッド知らないよ、とか言われてしまう。
@book.methodsとか調べてみたけど、確かにtag_withというメソッドは見つからない。
色々悩んだ末、ふと、acts_as_taggable_on_steroidsのREADMEを見たら、

p = Post.find(:first)
p.tag_list # ""
p.tag_list = "Funny, Silly"
p.save
p.reload.tag_list # "Funny, Silly"

って書いてあったので、試しにさっきのところを

@book = Book.new(params[:book])
@book.tag_list = params[:tag_list]
if @book.save

と書き換えたら、すんなり動いた。
なんでtag_with駄目なの……? と、少し悩んだけど、まあ今回は動いたから良しということに。
で。
区切り文字は、environment.rbで

TagList.delimiter = ","

とかで指定できるのか。指定しない場合は、","(半角カンマ)がデフォルトなのね。

あとは。
Book.find_tag_with(tag_name, option)で、tag_nameで指定したタグをつけられているのだけ拾ってくるとか。
Book.tag_count(option)で、[{:name => tag_name, :id => tag_id, :count => count}, ...]な感じでタグ毎の集計が返ってくる。
楽しい、楽しい。
acts_as_taggable_reduxの方はもっとお手軽らしいので、そっちも今度試してみよう。
だらだらと書いてしまった。