#contents *私家版:Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル [#t23e699d] オリジナルのページは[[こちら>http://qwik.jp/tritonn/rortutorial.html]] 2009年7月6日((日本ショウジョウバエ研究会第9回研究集会の夕食のとき))、某大学の某氏((http://www.cis.kit.ac.jp/~tomaru/jdrc7registration.html に連名でプログラムを公開したりしています……、全然某じゃないか))にRubyはやってないのかと尋ねられ、 そのときは、~ ブックマークはしているけどインストールしていない、最近はPerlばかり使ってて と答えたのです((系統情報の整理にPerlをかなり使っていたのです))。~ が、インストールしてしまったのでした。~ そこで、素のMySQLではなく、全文検索のできるsennaが組み込まれたMySQLである[[Tritonn>http://qwik.jp/tritonn/]]と[[Ruby on Rails>http://rubyonrails.org/]]をインストールし、[[Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル>http://qwik.jp/tritonn/rortutorial.html]]に従って動作確認をしようとしたところ、まったく動かなかったのです(7月20日のこと)。~ 原因はRuby on Railsのバージョンが2であったこと。チュートリアルはRuby on Railsのバージョン1に対してのものでした。~ そういった訳で、ほぼチュートリアルと同じ動作をする私家版を作らざるを得ず、作ったからには公開する次第です。7月中に公開できれば、6月はPerlやってたけど7月になったのでRubyにしたのさ、と言えたんですが((6月の誕生石が真珠、7月がルビー))、残念。 **バージョンなど [#i9926f9e] - ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32] (ActiveScriptRuby 1.8.7(p174) with-winsock2):http://arton.hp.infoseek.co.jp/indexj.html より入手 - Rails 2.3.2:http://rubyonrails.org/ より入手 - tritonn-1.0.12-mysql-5.0.67-win32.zip:http://sourceforge.jp/projects/tritonn/releases/ より入手。tritonnのページはhttp://qwik.jp/tritonn/。これは、 mysql Ver 14.12 Distrib 5.0.67, for Win32 (ia32) になる。 なお rubyの本家本元は、http://www.ruby-lang.org/ ruby、rails、tritonn は無事にインストールできていることとして、以下進んでください。項目はオリジナルに準じるよう試みてはいますが、Railsの大幅な変更に対応したので、かなり異なってしまったところもあります。 ** 1 アプリケーションの生成から入力フォーム作成まで [#na60ff24] ***事前準備 [#bb33c82f] Railsを開発するフォルダを決めます。 例:C:\Work ***Rails アプリケーションの作成 [#n28d85a0] コマンドプロンプトを開きます。事前準備で用意したディレクトリで以下のコマンドを入力します。 rails rordemo このコマンドを実行することで、自動にアプリケーションの一式が作られます。 ***プロジェクト作成 [#n89018aa] プロジェクト「rordemo」を作成し、データベースにMySQLを設定する(デフォルトではsqlite3) rails rordemo -d mysql rordemoプロジェクトが作成される。フォルダやファイルが一気にできる。 ***雛形作成 [#w7407c3a] cd rordemo ruby script/generate scaffold article content:text rordemoプロジェクトの雛形が作成される。フォルダやファイルが一気にできる。 ***テーブル作成 [#cf78c5a4] ○○/rordemo/db/migrate/○○_create_articles.rbを変更 オリジナル class CreateArticles < ActiveRecord::Migration def self.up create_table :articles do |t| t.text :content t.timestamps end end def self.down drop_table :articles end end 変更後 class CreateArticles < ActiveRecord::Migration def self.up create_table :articles, :options => "ENGINE = MYISAM" do |t| t.text :content t.timestamps end execute "ALTER TABLE articles change content content LONGTEXT" execute "ALTER TABLE articles add FULLTEXT INDEX USING NGRAM (content)" end def self.down drop_table :articles end end ※ 「execute "ALTER TABLE articles change content content LONGTEXT"」は、なくてもいいが、textは文字数が制限される rake db:create rake db:migrate ruby script/generate controller Search ruby script/server http://localhost:3000/Articles/ にアクセス Listing articles Content New article が見えればおっけい MySQLに接続 mysql - データベースを作成 create database rordemo_development; テーブルの作成 テーブルを作成し、以下に保存 [/rordemo/db/create.sql] DROP TABLE IF EXISTS `articles`; CREATE TABLE `articles` ( `id` int(11) NOT NULL auto_increment, `date` datetime NOT NULL default '2007-10-04 00:00:00', `content` longtext, PRIMARY KEY (`id`), FULLTEXT KEY `ft` USING NGRAM (`content`) ) ENGINE=MyISAM; 作ったテーブルをDBに挿入 mysql rordemo_development <db/create.sql -u root -h localhost Railsとデータベースの連携 次に、Railsからデータベースを参照できるようにします。 [rordemo/config/database.ymi] このファイルの中の以下の部分に注目してください。 username: root password: host: localhost この設定をを自分の環境に合わせて変更します。 今回はそのままで変更はありません。 development: adapter: mysql database: rordemo_development username: root password: host: localhost test: adapter: mysql database: rordemo_test username: root password: host: localhost production: adapter: mysql database: rordemo_production username: root password: host: localhost 日本語の設定 2箇所のファイルの書き換えを行います。 [config/enveronment.rb] に以下のコードを先頭に追加 $KCODE="utf8" [app/controllers/appllication.rb] を以下のように変更。これにより、作成ファイル全てにutf8が適応されます。 class ApplicationController < ActionController::Base before_filter :set_charset private def set_charset headers["Content-Type"] = "text/html; charset=utf8" end end 入力フォームの作成 generateを使用することで、簡単に入力フォームか作成されます。 ruby script/generate scaffold Article Admin 作成されるファイルは以下のとおり。 exists app/controllers/ exists app/helpers/ create app/views/admin exists app/views/layouts/ exists test/functional/ dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/article.rb create test/unit/article_test.rb create test/fixtures/articles.yml create app/views/admin/_form.rhtml create app/views/admin/list.rhtml create app/views/admin/show.rhtml create app/views/admin/new.rhtml create app/views/admin/edit.rhtml create app/controllers/admin_controller.rb create test/functional/admin_controller_test.rb create app/helpers/admin_helper.rb create app/views/layouts/admin.rhtml create public/stylesheets/scaffold.css これで一番簡単な入力フォームの完成! ページの閲覧 サーバ起動 これで一通りのパーツがそろいました。RailsにはWEBrickと呼ばれるwebサーバが同梱されていますので、それを利用してページが見られるか確認しましょう。 ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2007-10-03 17:40:29] INFO WEBrick 1.3.1 [2007-10-03 17:40:29] INFO ruby 1.8.6 (2007-09-23) [i386-mswin32] [2007-10-03 17:40:29] INFO WEBrick::HTTPServer#start: pid=6108 port=3000 (停止は Ctrl+c) ページの閲覧 http://localhost:3000/admin これで見られたら、第一段階が終了。 注)これからファイルのページの更新を行いますが、そのたびにサーバは停止しておくのがよいでしょう。 2 検索機能の追加 ページのの作成 generate を利用して、検索を行うページを作成します。 ruby script/generate controller Search index 以下のファイルが追加されます。 exists app/controllers/ exists app/helpers/ create app/views/search exists test/functional/ create app/controllers/search_controller.rb create test/functional/search_controller_test.rb create app/helpers/search_helper.rb create app/views/search/index.rhtml Searchは作成するコントローラ名で、indexはSearchコントローラにindex()メソッドをひとつ持たせるという意味になります。ここで最初のメソッドにindexとつけた理由は、「http://localhost:3000/search/」と入力した場合に自動的にindexメソッドが呼び出されるからです。このようにRailsでは、コントローラを呼び出す際に明示的にアクションを指定していないと自動的にindex()アクションが呼び出されるようになっています。 ページの閲覧 再びWebrickサーバを起動し、以下にアクセス http://localhost:3000/search/ ./rortutorial.files/search_index1.jpg まだ雛形を作成しただけなのでこの様な画面がいればOK. 検索フォームの作成 追加すべきファイル コントローラにメソッドを追加 [app/controllers/search_controller.rb] を以下のデータに変更します。 class SearchController < ApplicationController #def index # @articles = Article.items #end def search_text @articles = Article.search_text(params[:query]) flash.now[:notice] = "Search result#{@articles.size}found." render(:action => 'search_text') end end モデルにメソッドを追加 [app/models/article.rb] を以下のデータに変更 class Article < ActiveRecord::Base def self.search_text(query) find_by_sql([" select date, match(content) against (?) as score, kwic(content, 150,3,1,'',' ... ', ?, '<span id=word>', '</span>') as snippet from articles where match(content) against(?) order by score desc limit 20", "#{query}","#{query}", "#{query}"]) end end ビューの作成と編集 [app/views/search/search_text.rhtml] を新規作成し、以下のように編集。 <html> <body> <table cellpadding="5" cellspacing="0"> <% for article in @articles %> <tr valign="top" class="catalogentry"> <td align="left"> <p>date <%=article.date%><p> <p>score <%=article.score%><p> <p>snippet <%=article.snippet%><p> </td> </tr> <tr><td colspan="2"><div class="separator"> </div></td></tr> <% end %> </table> </body> </html> [app/views/search/index.rhtml] を以下のデータに変更する。 <html> <body> <p><label for="article_title"><b>検索</b></label></br> <%= form_tag(:action => :search_text) %> <%= text_field(:query,nil) -%><%= submit_tag "検索実行" %></p> <%= end_form_tag %> <br> </body> </html> ページの閲覧 再びWebrickサーバを起動し、以下にアクセス http://localhost:3000/search/ ./rortutorial.files/search_image.jpg これで検索ページが表示されれば成功! search_image.jpg search_image.jpg download スタイルシートのカスタマイズ [app/views/search/search_text.rhtml] を編集し、検索結果ページにスタイルシートを適用するように設定しましょう。 <head> <link href="/stylesheets/scaffold.css" media="all" rel="Stylesheet" type="text/css" /> </head> [public/stylesheets/scaffold.css] にキーワードに対応したスタイルを追記します。 #word { background-color: #faf } これで検索結果画面のキーワード部分に背景色がつきます。 リンクの追加 後は好みでリンクを追加すると良いかもしれません。 今のままだとページ間の移動がしにくいパタンがあるのでリンクをいくつか追加します。 [app/views/search/search_text.rhtml] ページ先頭に以下の一行を追加。 <%= link_to 'Back', :action => '' %> これで検索結果画面から、検索画面へ戻れるようになります。 [app/views/search/index.rhtml] ページ末尾に以下の一行を追加。 <a href="../admin/">閲覧/登録</a> これで検索画面から、記事登録/閲覧画面へ飛べるようになります。 [app/views/admin/list.rhtml] ページ末尾に以下の一行を追加。 <br /><a href="../search">検索</a> これで記事登録/閲覧画面から検索画面に飛べるようになります。 |Today:&counter(today);|Yesterday:&counter(yesterday);|Total:&counter(); since 2 August 2009|