ブックマーク管理

引き続きRailsを触っている。忘れないうちに、ある程度慣れとくと、少し時間が経っても覚えてそう。というか、別のこともやりたいのだが...。

ということで、Bookmarkのチュートリアルを真似て、もう少し遊んで見ることにした。

Tableの作成

10分...のやつの詳細は忘れたので、手で書きながら思い出してみる。まずは、Table 定義から。MySQLのvarcharは、255バイトまでらしいので、もうちょっとURLを長く格納できるようにtextを使ってみる。blob を使ったら、scaffold は対応していないようで、text に変更した。この辺のバイトとかの情報は、 MySQL 4.1 リファレンスマニュアル 6.2.6. 各カラム型に必要な記憶容量 辺りを参照した。

ということで、Modelに対応する為の テーブル bookmarks を作成する。(書きながら気が付いたけど、この後で出てくるコードは、タイトルの長さを切り詰めてないや...255バイトに収まるようにしないとエラーだな)。

以下で出てくるファイルのパスは、railsをセットアップしたディレクトリからの相対パス。また、http://host/path/ とかは、環境に合わせて適時設定する必要がある。

 create table bookmarks
 (
        id integer primary key auto_increment,
        title varchar(255),
        url text
 );
雛型の作成

ここで、ControllerとModelを作成する。

 $ script/generate controller bookmark
 $ script/generate model bookmark

そして、作成されたControllerを修正する。app/controllers/bookmark_controller.rb をいじればよいはず。scaffold というのを使って、次のようにすると、デフォルトの動作で簡単なDBの操作画面を作成してくれるそうな。

class BookmarkController < ApplicationController
  scaffold :bookmark
end

んで、http://host/path/bookmark みたいにアクセスすると簡単なリストを表示してくれる。ここら辺りまでは、チュートリアルでやったので、たどり着ける。このままだとscaffold のカスタマイズが出来ない。どうやってやるのかなと思ったら、
RubyOnRails を使ってみる 【第 4 回】ActionPack
に載っていた。generate で指定すれば良いようだ。ということで次のようにやってみる(Bookmarkの引き数無しで、どんな引き数を必要とするのか説明が出た)。

  $ ./script/generate scaffold Bookmark

これで、幾つか後々修正可能なテンプレートが作成された。先ほどのコマンドでは、Modelは指定されているけど、Controllerは指定していないので、bookmarks (複数形) がデフォルトで対応するらしい。その為、bookmark_controller.rb ではなく、これからは、bookmarks を使うことにしよう。とりあえず、http://host/path/bookmarks という感じでアクセスして動くことを確認すれば良いみたい。

実現したいこと その1: URLをリンクにしたい。

URLがリンクじゃないとBookmarkも使いにくいので、それを考える。とりあえず、リストされるやつが直ればよいだろう。ということで、 app/views/bookmarks/list.rhtml を編集する。テーブルのヘッダ部分と、Tableのカラム部分を変更する。各カラムごとの動作は、消して次のようにした。

  ...(省略)...
  <td><%= link_to bookmark.title, bookmark["url"] %></td>
  ...(省略)...

これで、ブラウザの表示タイトルは、ブックマークのタイトルで、リンク先は登録したURLになってくれた。

実現したいこと その2: Bookmarkletを利用して登録したい。

Railsとあんまり関係なくなるけど(笑、BookmarkletでアクティブなURLを登録できるようにしたい。せっかくなので?サーバサイドで Bookmarklet をメンテナンスできるように bookmarkletの文字数制限を無くす を参考にクライアント用のURLは src のURLだけを http://host/path/javascripts/createbookmark.js というような サーバの javascript ファイルを指すようにした。

サーバのjava scriptファイルは、public/javascripts 以下に置けばブラウザからアクセスできるので、public/javascripts/createbookmark.js ファイルを作成する。中身は、こんな風だ(実際には、bookmark[title] や bookmark[url] は、予めエスケープされた文字を使ったほうがパフォーマンス的には良いはず)。

function getBookmarkLocation(title, url) {
  return 'http://host/path/bookmarks/create/?commit=Create&' +
    encodeURIComponent('bookmark[title]') + '=' + encodeURIComponent(title) + '&' +
    encodeURIComponent('bookmark[url]')   + '=' + encodeURIComponent(url);
}
location.href=getBookmarkLocation(document.title, location.href);

これぐらい、そのままクライアントに渡せばいいじゃん!っておもうけど、練習もかねて。というか、最初、bookmark でやってたので、これだとサーバを直せばいいのでやっぱ楽かも。URLがきまってしまえば、必要ないだろうけど...。

このパスは、list のページから新規作成に飛んで、そこのソースを参考にした。その引き数をまんまコピーしてJavaScriptからのGetリクエストに仕立てれば良さそうだった。で、実際登録できた。Bookmarkletとか、名前は知っていたが、あんまり動作を詳しく見たことが無かった。でも、やっぱり、実際に使ってみると便利かも。。少なくとも、Bookmarkを登録するのは楽だ。

と、ここまで書いたけど、先ほどの Bookmarkletの動作を確認したのは、FirefoxIEで、Sleipnir とかはうまく動かないみたい(いまだ、1.66なので、2.0の動作は不明だけど...)。でも、不便なので、Sleipnir でどうにかならないか調べてみた。色々、確認してみたが、結論としては、Bookmarkじゃ無理っぽい気がしてきた。そもそも、javascript:... を解釈してくれないみたいだし。ただ、Sleipnirスクリプトを使えば、ActiveなタブのDocumentが得られ、そこから、titleを持ってきたりと色々できる。さっきみたいに、サーバで管理できたらかっこいいけど、Sleipnirで OneClick で登録できるなら、それはそれで面白そうだ。Scriptが動作するようにActiveにして、 「スクリプト」->「スクリプトの新規作成」 と進んで、次のような感じで作成すればうまく行った。初めて作成したんだけど、これも便利そうだなぁ。というか、きっとSleipnirの便利なところは、この辺なんだろうけど(動きそうだけど 2.0 で動作確認してません)。

var pnir;
var document;
var id;

function getBookmarkLocation(title, url) {
  return 'http://host/path/bookmark/create/?commit=Create&' +
    encodeURIComponent('bookmark[title]') + '=' + encodeURIComponent(title) + '&' +
    encodeURIComponent('bookmark[url]')   + '=' + encodeURIComponent(url);
}

pnir     = new ActiveXObject("Sleipnir.API");
id       = pnir.GetDocumentID(pnir.ActiveIndex);
document = pnir.GetDocumentObject(id);

if (document == null)  {
    pnir.MessageBox("Document オブジェクトを作成できません");
}
else {
    pnir.NewWindow(getBookmarkLocation(document.title, pnir.URL), false);
    document = null;
}

pnir = null;

これを スクリプトとして登録して、実行すれば、アクティブなタブのタイトルとURLを登録してくれます。

こんな風に、すればもうちょっと使いやすいブックマーク管理ツールになった気がする。