Rails3 で acts_as_tritonn
Rails2 + Tritonn の時には結構お世話になっていた acts_as_tritonn を Rails3 で使ってみました。
インストール
$ rails new tritonn_example -d mysql $ cd tritonn_example $ rails plugin install git://github.com/ryu00026/acts_as_tritonn.git
使ってみる
config/database.yml に Tritonn への接続設定を記述し、rails console で接続。
find_fulltext を呼び出したところで、以下のようなエラーが発生しました。
$ rails c Loading development environment (Rails 3.0.9) ruby-1.9.2-p180 :001 > Entry.find_fulltext(:title => 'Ruby') NameError: uninitialized constant ActiveSupport::Multibyte::Handlers from /home/akishin/src/ruby/tritonn_example/vendor/plugins/acts_as_tritonn/lib/tritonn/searchable.rb:64:in `block in fulltext' from /home/akishin/src/ruby/tritonn_example/vendor/plugins/acts_as_tritonn/lib/tritonn/searchable.rb:60:in `each_pair' from /home/akishin/src/ruby/tritonn_example/vendor/plugins/acts_as_tritonn/lib/tritonn/searchable.rb:60:in `fulltext' from /home/akishin/src/ruby/tritonn_example/vendor/plugins/acts_as_tritonn/lib/tritonn/searchable.rb:50:in `find_fulltext' from (irb):1 from /home/akishin/src/ruby/tritonn_example/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start' from /home/akishin/src/ruby/tritonn_example/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start' from /home/akishin/src/ruby/tritonn_example/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands.rb:23:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>'
以前 2.2 系で使おうとした時に見たことあるエラーです。
その時は以下のサイトにお世話になったのですが、今見るとどうやら消えてしまっているようですね。
whatever I wanna talk - MySQL tritonn (senna) で全文検索 on Rails 2.2.2
http://www.silver-island.com/jp/blog/2009/02/mysql_triton_senna_on_rails_22_1.html
2.2 の時は、こちらサイトで教えて頂いた、searchable.rb に対する以下の修正を行うことでこのエラーは回避できていました。
$ vim vendor/plugins/acts_as_tritonn/lib/tritonn/searchable.rb
64行目の辺りを以下のように修正。
# ANDか通常の検索 ary = string.split(/[#{ActiveSupport::Multibyte::Handlers::UTF8Handler.codepoints_to_pattern(ActiveSupport::Multibyte::Handlers::UTF8Handler::UNICODE_WHITESPACE)}]+/)
↓
# ANDか通常の検索 if ActiveSupport::VERSION::MAJOR >=2 and ActiveSupport::VERSION::MINOR >=2 ary = string.split(/[#{ActiveSupport::Multibyte::Chars.codepoints_to_pattern(ActiveSupport::Multibyte::Chars::UNICODE_WHITESPACE)}]+/) else ary = string.split(/[#{ActiveSupport::Multibyte::Handlers::UTF8Handler.codepoints_to_pattern(ActiveSupport::Multibyte::Handlers::UTF8Handler::UNICODE_WHITESPACE)}]+/) end
※ 移転先が見つからななかったため、こちら転載させて頂きました。
修正内容
エラーの内容からすると今回も同様の修正になりそうです。
念のため、Rails3 で codepoints_to_pattern メソッドがどうなったか調べてみます。
codepoints_to_pattern (ActiveSupport::Multibyte::Chars) - APIdock
http://apidock.com/rails/ActiveSupport/Multibyte/Chars/codepoints_to_pattern/class
ここを読むと、ActiveSupport::Multibyte::Chars.codepoints_to_pattern は 2.3.8 までで、現在は同等のメソッドとして ActiveSupport::Multibyte::Unicode#codepoints_to_pattern を使え、ということのようですね。
また、引数で指定している ActiveSupport::Multibyte::Chars::UNICODE_WHITESPACE に関しても、ActiveSupport::Multibyte::Unicode::WHITESPACE の方を使うようになったみたいです。
これらを踏まえ、searchable.rb を以下のように修正してみました。
# ANDか通常の検索 if ActiveSupport::VERSION::MAJOR >=3 ary = string.split(/[#{ActiveSupport::Multibyte::Unicode.codepoints_to_pattern(ActiveSupport::Multibyte::Unicode::WHITESPACE)}]+/) elsif ActiveSupport::VERSION::MAJOR >=2 and ActiveSupport::VERSION::MINOR >=2 ary = string.split(/[#{ActiveSupport::Multibyte::Chars.codepoints_to_pattern(ActiveSupport::Multibyte::Chars::UNICODE_WHITESPACE)}]+/) else ary = string.split(/[#{ActiveSupport::Multibyte::Handlers::UTF8Handler.codepoints_to_pattern(ActiveSupport::Multibyte::Handlers::UTF8Handler::UNICODE_WHITESPACE)}]+/) end
rails console で確認すると今度はエラーは発生せず、検索結果も取得できています。
log/development.log に出力されるログを見ても以下のように、以前と同様のクエリが出力されていました。
SELECT `entries`.* FROM `entries` WHERE (MATCH(title) AGAINST (" +Ruby" IN BOOLEAN MODE))
これで修正は OK と言えそうです。
Tritonn はお手軽に全文検索システムを作るのに便利なので、これで Rails3 からも気軽に使う事ができるようになったのは嬉しいです。