Sunday, December 14, 2008

PDFPack.app

名刺をデザインしてA4の用紙に複数面割り付けて印刷しようと思ったけど、どうすればいいのかわからない。

DTPの知識(と高価なソフトウェア?)があれば簡単なことだろうとは思うけれど、適切なフリーソフトも見つからない。Mac OS X プリンタダイアログ標準のレイアウト機能の複数ページを1枚に割り付ける方法ではあらかじめ同じデザインのページのコピーを作成してPDFなどにまとめる必要があるし、そもそも名刺などの場合はサイズが重要なので1ページ分の出力サイズを指定できないので使えない。

やりたいことは実にシンプルで、名刺やカードなど小さいサイズで同じデザインのものを、出力する用紙(A4など)1枚に対して複数印刷したいだけなので、RubyCocoa のリハビリを兼ねて、その目的を達成するためだけのフィルターのようなツール PDFPack.app を作ってみました。

単体のアプリケーションとしても動きますが、インストールすると PDF Service (プリントダイアログの左下の "PDF" ボタンで出てくるメニュー)として登録されるので、以下のような使い方ができます。

使用例として名刺を印刷する場合


1. カードをデザインするツール (僕は OminiGraffle を使いました)のページ設定(新しいアプリケーションではプリントダイアログに統合されているようです)の用紙サイズのカスタムサイズを管理で 5.5 x 9.1cmの用紙を追加して選択

2. そのサイズにあわせて名刺をデザインしてプリントダイアログ(Cmd+P)を開いて、PDFメニューから "PDFPack" を選択


3. PDFPack.app が起動するので必要ならマージンを調整して印刷

ちなみに、用紙はエーワンマルチカード#51002、プリンタはHP Deskjet 5551を利用。このA4サイズの用紙では 5.5x9.1cm のサイズを10面印刷するときに左右の余白は1.4cm、上下の余白が 1.1cm になるのですが、PDFPack のバグかプリンタの仕様か、bottom margin を 0.9cm と 0.3mm 小さく設定しないとうまい具合に印刷できませんでした。

蛇足ですが、似たようなツールに Hipster PDA を印刷する PagePacker というものがあります。PDFPack も1枚の紙に異なる種類のカードを印刷できると便利かもしれません。

Monday, November 24, 2008

mysql_xml2google_notebook_atom

Google Notebook を使うようになってから、以前に作ったメモを溜める web application が必要なくなったけれど、メモの内容は参照したいことがあったので、Google Notebook にインポートしてみました。

その web application は mysql を使っていたので、 mysql コマンドの --xml オプションで出力した結果の XML を Google Notebook がインポートできる Atom フォーマットの XML に変換するスクリプト mysql_xml2google_notebook_atom.rb を書き、変換してからインポート。

余談ですが、Google Notebook には Atom フォーマットでエクスポートする機能もあります。しかし、残念なことに XML の encoding を iso-8859-1 (latin-1) から変更する方法が分からないので、日本語のノートは Atom ではエクスポートできない。
どこにフィードバックを送ればよいのかわからないので、Google Notebook Official Blog の記事にコメントしました。オープンソースでないとこういうところがもどかしい。

Friday, November 14, 2008

Polymorphic_url should compact given array

ネストした URL にしたい場合、たとえば /groups/1/users だと、routes.rb は、こんな感じ。
map.resources :groups, :has_many => :users

さらに、 group を指定しないユーザーの一覧を取得したい場合 (/users) には resources を追加。
map.resouces :users


polymorphic_path を使うと
polymorphic_path([@group, :users]) # A
polymorphic_path(:users) # B


ここで、 @group が nil だったら、 A は B と同じ解釈をしてほしいいのだけど、
"NoMethodError: undefined method nil_class_users_url'"

のようにエラーになってしまうので、patch を投げたら、 commit された。

非常に小さな変更だけど、パッチが受け入れられるとうれしいもんですね。

Thursday, October 30, 2008

How to skip ActionController::Filters with block

before_filter :foo
def foo
...
end

メソッド名のシンボルを与えてフィルターを指定する場合、
skip_before_filter :foo

でスキップできるけど、
before_filter do |controller|
...
end

ブロックを使った場合スキップする方法がわからないので ActionController::Filters の実装を調べたら、
before_filter :identifier => :foo do |controller|
...
end

とすることで、
skip_before_filter :foo

できることがわかった。

:identifier オプションは ActiveSupport::Callbacks::Callback のアトリビュートなので、 ActionController::Filters の実装が ActiveSupport::Callbacks::Callback を使っていない 2.0.X 以前のバージョンでは使えないと思われるので注意。

Monday, October 27, 2008

Fixing false latin1 encoding MySQL database into utf8

Rails 2.2 には mysql pure ruby adapter が含まれていないので、アップデートしたときに mysql native adapter を入れていない事に気がついた。
 sudo gem install mysql

その後、アプリケーションを再起動したら、データベースに保存されている文字列の表示が思いっきり文字化けしてしまった。
database.yml をよく見てみると、
 encoding: utf-8

しまった。 MySQL adapter の場合、
 encoding: utf8

と書かなければいけなかったのだ。
MySQL native adapter のデフォルトエンコーディングは latin1 らしいので、一度、 latin1 としてダンプして、
 mysqldump --default-character-set=latin1 -u root foo_production > foo.mysql

ダンプファイルの SET NAMES を書き換え
- /*!40101 SET NAMES latin1 */;
+ /*!40101 SET NAMES utf8 */;

database の再作成
mysql -u root -e "drop database foo_production; create database foo_production"

そして、ロード
mysql -u root foo_production < foo.sql


つまらないバッドノウハウで恐縮ですが、以前にも同じ事をやらかしてしまったことがあったので役に立つこともあるかと。

Wednesday, October 22, 2008

Passenger: Keeping ApplicationSpawner alive speeds up spawning an instance

アクセス頻度が少ないサイトで Passenger を使っている場合、しばらくしてからアクセスするとデプロイ直後や apache のリスタート直後と同じくらいレスポンスが遅くなることがあります。

Passenger は fork 時の copy-on-write により複数のアプリケーションプロセスが消費する実メモリのサイズが小さくなるようになっていて、その fork も以下のような3段階で行っているようです。

  1. 最初に起動する spawn server から fork して、 Rails をロード (framework spawner)

  2. framework spawner から fork して、アプリケーションをロード (application spawner)

  3. application spawner から fork して、リクエストを処理する過程で必要なファイルをオートロード (application instance)


spawn server は apache が終了するまで生きているようなんですけど、 framework spawner と application spawner にはタイムアウトする時間が設定されていて、 Passenger 2.0.3 のデフォルトではそれぞれ、30分、10分となっています。
したがって、前回のアクセスから10分過ぎると、再度 application spawner から生成し直すのでレスポンスに時間がかかります。

ということは、 application spawner のタイムアウト時間を十分に長くすればよいということで、無理矢理 passenger のファイルを変更。

/usr/lib/ruby/gems/1.8/gems/passenger-2.0.3/lib/passenger/constants.rb:
-   FRAMEWORK_SPAWNER_MAX_IDLE_TIME = 30 * 60
- APP_SPAWNER_MAX_IDLE_TIME = 10 * 60
+ # keep them alive for a week
+ FRAMEWORK_SPAWNER_MAX_IDLE_TIME = 7 * 24 * 60 * 60
+ APP_SPAWNER_MAX_IDLE_TIME = 7 * 24 * 60 * 60


Passenger 2.0.3 の段階では上記のような変更が必要ですが、 将来のバージョンでは apache の設定ファイルで RailsFrameworkSpawnerIdleTime, RailsAppSpawnerIdleTime を指定すれば変更できるようになるようです。

また、 Phusion Passenger users guide - 8.3 Capistrano Recipe の note に書いてあるように、デプロイ後に新しい application spawner が生成されても古いのが残ったままになるので、デプロイするときに kill。

config/deploy.rb:
namespace :passenger do
namespace :application_spawner do
desc "kill Passenger ApplicationSpawner"
task :kill do
run "kill $( passenger-memory-stats | grep 'Passenger ApplicationSpawner' | awk '{ print $1 }' ) || true"
end
after "deploy:update_code", "passenger:application_spawner:kill"
end
end

Passenger のドキュメントに書かれているように "Passenger spawn server" を殺すには root 権限が必要なので代わりに application spawner を kill。なんとなく不安定な気もするけど、これで様子を見ることにします。

参考資料:
Wishlist — passenger — GitHub
RailsFrameworkSpawnerIdleTime and RailsAppSpawnerIdleTime - Phusion Passenger Discussions | Google Groups
Modrails ... Slow first request ... - Phusion Passenger Discussions | Google Groups

Sunday, October 19, 2008

URL options for polymorphic_url

routes.rb:
 map.resources :users 

というリソースへのルートを定義している場合、

 polymorphic_url(:users) # => "/users"

という具合になります。

そこで、追加のパラメータをあたえると
 polymorphic_url(:users, :foo => 1) # => "/users?foo=1"

となることを期待する訳なんですけど、 Rails 2.1.1 ではそうはならなくて、URLパラメータが付かない一つ前の例と同じパスが返ってくる。

#880 URL options for polymorphic_url - Ruby on Rails - rails

edge では修正されてますけど、リリースするまでは、以下のような汚いパッチでごまかします。

if Rails::VERSION::STRING == "2.1.1"
# polymorphic_url should accept extra parameter options
# polymorphic_path(:projects, :foo => 1) # should be => /projects?foo=1
# This portion of code fixes this issue in a quick and dirty way.
ActionController::PolymorphicRoutes.module_eval do
def polymorphic_url_with_params(record_or_hash_or_array, options = {})
url = polymorphic_url_without_params(record_or_hash_or_array, options)
url_options = options.except(:action, :routing_type, :format)
unless url_options.blank?
url += "?" + url_options.to_param
end
url
end
alias_method_chain :polymorphic_url, :params

%w(edit new formatted).each do |action|
module_eval <<-EOT, __FILE__, __LINE__
def #{action}_polymorphic_url(record_or_hash, options = {})
polymorphic_url(record_or_hash, options.merge(:action => "#{action}"))
end

def #{action}_polymorphic_path(record_or_hash, options = {})
polymorphic_url(record_or_hash, options.merge(:action => "#{action}", :routing_type => :path))
end
EOT
end
end
end

Tuesday, October 14, 2008

Cloning a local git repository into a remote host

リモートリポジトリをローカルにクローンする方法は知っているけど、ローカルリポジトリのクローンをリモートに作る方法がいまいちわからなかったので調べてみました(より標準的な方法を知っているひとはコメントください)。

まずは、ローカルにベアリポジトリのクローンを作成してアーカイブ。
 $ git clone --bare -l foo/.git foo.git
$ tar czf foo.git.tar.gz foo.git

これをリモートにコピーして展開すればOK

あとは、ローカルの clone 元の .git/config に以下の行を追加
[remote "origin"]
url = ssh://name.of.host/path/to/repos.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

git push はデフォルトで "origin" リポジトリのすべてのブランチを push するので、.git/config に remote "origin" のセクションがあれば、その url と fetch として記述されている refspec のマッピングを利用します。

また、 git pull はデフォルトで "origin" リポジトリから、 .git/config の branch セクションの remote が pull するリポジトリと一致するブランチを pull する (たぶん)。

よって、上記の設定により "git push", "git pull" だけで svn commit/update 相当の操作ができる。

ちなみに、これらの設定は
 git clone ssh://name.of.host/path/to/repos.git 
で得られるクローンリポジトリの設定と同じです。

Wednesday, October 8, 2008

Test-driven learning

Andrew Hunt のブログの記事 /\ndy - Test-driven Learning より。TDD (Test-Driven Development) から思いついたと書いてます。

それが最良の方法かどうかはわからないけど、やっぱり「習うより慣れよ」というのは効果があると思います。特に学習するコトが今までの経験から推測できなかったりするときには特に。今までの経験が活用できる場合は頭の中でテストがある程度できるけど、そうでない場合は実際に手を動かしてそれがどういう結果になるかどうかのフィードバックが得られないとなかなか進めない。

すいません、当たり前の事書いて...。

Friday, August 29, 2008

The insanity of flavored mineral water

先日、ホームで電車を待っているときにノドが乾いたので、自動販売機で「Volvic Fruit Kiss Lemon」という飲み物を買った。あまりよく見ずに自動販売機のボタンを押したので、口にしてはじめて、それが香料入り飲料水だと気がついた。原材料名の一覧には香料としか書いていないのでそれが天然なのか合成なのか定かではないが、後味の悪さから合成だと思う。

なんてアホなものを買ってしまったのだろうと反省した。

ただでさえ、大量のエネルギーを費やしてわざわざフランスから水を輸入しているのは、その水質に価値があるからだと思うのだけど、それを香料で台無しにしているなんて、なんてアホなんだろう。

Tuesday, July 22, 2008

EmacsClient.app

僕はソースコードの編集に、Leopard に最初から入っている emacs を使ってます。
Leopard のターミナルでは日本語の入力も問題なくできるのですが、 ネイティブアプリケーションのように Dock アイコンにファイルをドロップすることでファイルを簡単に開けないので、find-file のミニバッファの内容を空にしてからターミナルのウィンドウにファイルをドロップしなければならないのが面倒です。

AquaEmacs, CarbonEmacs などを使えばドラッグ&ドロップも問題ないのですが、なんとなく余計なものを入れたくないので emacsclient を実行するだけの簡単なアプリケーションをつくればいいかな、誰か作ってないかなと "EmacsClient.app" を探したところ、 Platypus というスクリプトを実行するアプリケーションを簡単に作成できるツールを見つけました。

以下のようなシェルスクリプトを作成して、
emacsclient.sh

/usr/bin/emacsclient -n "$1"


スクリーンショットのような設定で、"Create" するだけで


EmacsClient.app が生成されます。

あ、すでに開いている emacs で M-x server-start するのをお忘れなく。

Tuesday, July 1, 2008

Getting wherefrom of downloaded files

Mac OS X の Safari でファイルをダウンロードすると、ファイルのメタデータとして "where from" という情報が保存され、「あれーこのファイルどこから取ってきたんだっけ?」という疑問に答えてくれます。

Finder の情報を見る確認することはできるんですけど、残念ながら選択してクリップボード(ペーストボード)へのコピーができません。



そういうときは、ターミナルで、 "mdls" + スペースを入力してから、ダウンロードしたファイルをターミナルにドロップすると...。


$ mdls /Users/hiroshi/Desktop/Velocity/High\ Performance\ Ajax\ Applications\ Presentation.ppt
....
kMDItemWhereFroms = (
"http://en.oreilly.com/velocity2008/public/asset/attachment/1956",
"http://en.oreilly.com/velocity2008/public/schedule/proceedings"
)

Thursday, April 24, 2008

a ruby to javascript bridge, Johnson

こんなものがあった。

http://github.com/jbarnette/johnson/tree/master
http://tenderlovemaking.com/2008/04/23/take-it-to-the-limit-one-more-time

Firefox が使っている javascript エンジン
http://www.mozilla.org/js/spidermonkey/
の ruby bridge のようだ。

README.txt に書いてあるとおりに gem install jhonson できなかったので、

git clone git://github.com/jbarnette/johnson.git
cd johnson
rake

irb で試すとこんな感じ
irb -I./lib -rjohnson
>> Johnson.evaluate("var foo = {x: 1}; foo").x
=> 1

これで、 rails アプリケーションで使っている .js のテストができるといいな。

Friday, April 11, 2008

My Spotlight in Leopard goes mad

数日前から Spotlight が index を何度も作成しようと試みるようになった。



コンソールにはこんなログが

08/04/11 4/11(金)16:18:04 mds[2477] /SourceCache/Spotlight/Spotlight-398.7/index/ContentIndex/FlatStore.c:706: failed assertion 'pageSize > 0' /.Spotlight-V100/Store-V1/Stores/E67A0F96-8AFF-43AF-B2AD-6665DE9CAD94/2.indexArrays flat store
08/04/11 4/11(金)16:18:04 mds[2477] (/)(Error) IndexCI in mergeIndexDataTrampoline:Caught mach exception. Fun Fun Fun.
08/04/11 4/11(金)16:18:04 mds[2477] /SourceCache/Spotlight/Spotlight-398.7/index/ContentIndex/CIMerging.c:216: failed assertion '!buffers->badIndex' /.Spotlight-V100/Store-V1/Stores/E67A0F96-8AFF-43AF-B2AD-6665DE9CAD94/0.indexHead corrupt ro index need to rebuild 0.
08/04/11 4/11(金)16:18:07 ReportCrash[2635] Formulating crash report for process mds[2477]


残念ながら、いろいろ調べてみたけど解決しないので、Leopard を再インストールすることに決めました。

Thursday, March 6, 2008

public.generic-pc.icns

Leopard の Finder には Windowsファイル共有のホストが見つかると PC を表すアイコンが表示されます。
通常は Finder のサイドバーに小さく表示されているだけなのであまり気にしてなかったのですが、ある日じっくり見てみると...。



Tiger までのアイコンの最大サイズは 128x128 だったんですが、Leopard から 512x512 になって (たぶん)640x480で表示されるあの画面の文字が辛うじて読み取れます。

アイコンファイルはココにあります。
/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/public.generic-pc.icns

Wednesday, February 20, 2008

VirtualBox beta3

MacWindows.com に VirtualBox beta3 がリリースされ、ホストOSとして Leopard もサポートされたと書いてあったので早速試してみた。



GUI はヤバイくらいダサく(OS9時代に作ったのか?)、メニュー項目に "About" が無く、Windows版と同じリソースを使っているのかショートカットのアルファベットが書いてあったり、かなりダメだが、



Parallels 2.0 のように Linux ゲストの時計を同期させる機能が欠如していたり(3.0 では対応したらしい)、VMWare のように VMWare tools を入れるという面倒なことをしなくても時計はホストと同期がとれているようだ。

Ubuntu の iso で起動させてみただけで、まだ分からないけど、Parallels も VMWare もMac 版は無料ではないので VirtualBox でもよいかもしれない。

Sunday, February 17, 2008

rescue_from() and Proc#bind()

Rails 2.0 の新機能に rescue_from(exception_class) という地味なやつがあります。いままでは、 ApplicationController などで rescue_action などをオーバライドして引数に与えられる exception を case ... when で処理するというわかりやすいけど、ダサイ方法で対応してきました。rescue_from を使うとこんな感じに書けます。


class UnauthorizedError < RuntimeError; end

class ApplicationController < ActionController::Base
...
before_fiter :login_required
def login_required
raise UnauthorizedError
end

rescue_from UnauthorizedError do
redirect_to login_path(:return_to => request.request_uri)
end
end


before_filter などにブロックを与える場合、そのブロックの self はそのコントローラのクラスなので、ブロックパラメータ controller を使うか、上記のようにインスタンスメソッドのシンボルを与える方法を使います。 ApplicationController で login_required のようなフィルタを追加した場合、かならず skip_filter したいケースがあるのでこの場合はいいんですけど、 before_fiter :foo; def :foo; ... end と冗長な書き方がウザイときもあります。

それと比べて、 rescue_from のブロックの中身はなぜかインスタンスメソッドと同じように書けます。Ruby 標準にはそんな機能はない思ってたのにと調べたら、秘密は ActiveSupport の Proc#bind() でした。

以上。

Sunday, January 27, 2008

NSPreferredMailCharset on Leopard

Apple の Mail.app にはユーザーがデフォルトで使用する送信メールのエンコーディングを選択できないという欠陥があります。新規にメールを作成する毎にはメニューから選択することにより変更できますが、環境設定の項目にはありません。

Tiger では defaults コマンドで NSPreferredMailCharset を設定することにより送信メールのデフォルトエンコーディングを設定することができたのですが(Apple のサポート情報)、Leopard ではその機能が縮退してしまっているようで動作しません。

日本語環境で利用している場合にメールを新規作成すると初期のエンコーディングは「自動」となっていて、たいていの場合はよろしくやってくれる(たぶんutf-8になる)のですが、たまに "簡体字中国語(Big 5)" で送ってくれたりしやがるので、「ヒロシさんまたメールが文字化けしてるんですけど」というクレームに Mac ユーザーとして恥ずかしくなり、デフォルトのエンコーディングを設定するプラグインを作りました。

自分だけが利用する分には ISO-2022-JP 固定で問題ないので、現状のバージョン (0.1) ではソースコードにハードコーディングしてしまっていますが、他のエンコーディングにしたい人はリクエストください。

Apple の日本やヨーロッパの法人がその問題に気がついていないのか、力が弱いのかわかりませんが、Mac の svn で濁点などが含まれるファイル名を扱うときの問題といい、 Apple のアメリカ人的考え(ascii, latin-1 以外のエンコーディングのことをまじめに考えていない)には残念に思います。

2009-09-12: Snow Leopard ではこのプラグインが動かないという報告を受けましたが、僕の mac は core duo の 初期型 MacBook でメリットを感じられなかったのでアップグレードしてません。ごめんなさい。
誰かプログラム書いたり出来る人で Snow Leopard 持ってる人がいたら プラグインの READMEの情報をヒントになんとかしてくれませんか。

Saturday, January 12, 2008

Resolving IP address for Mac, Linux and Windows each other by names

(ルーターを介さない)同一セグメント内ならば、 Mac 同士は DNS や hosts に登録しなくても "hiroshi-macbook.local" のような名前で IPアドレスを解決できます。 Mac を使っている人にとっては当たり前なので、Linux や Windows のホストにアクセスするときに環境によってはコロコロと変わる IP アドレスを指定しなければならないとストレスが溜まります。

Debian Etch, CentOS 5, Windows でその問題を解決する方法を紹介します。

Debian Etch



Avahi Daemon をインストール

$ sudo apt-get install avahi-daemon
$ uname -a
Linux hiroshi-etch 2.6.18-5-686 #1 SMP Mon Dec 24 16:41:07 UTC 2007 i686 GNU/Linux


これで、同じネットワークセグメント内の Mac などから、hiroshi-etch.local という名前でアクセスできるようになります。

$ ssh hiroshi-etch.local


逆に Linux から他のホストの名前解決ができるようにするには、

$ sudo apt-get install libnss-mdns


CentOS 5



$ sudo yum install avahi


nss-mdns のパッケージは無いようなので、(nss-mdns)

$ curl -O http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-0.10.tar.gz
$ tar xzf nss-mdns-0.10.tar.gz
$ ./configure
$ make
$ sudo make install


/etc/nsswitch.conf の "hosts:" の行を以下のように書き換える (詳細は README を参照)

hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4

これで、他の .local ホスト名を解決できるようになる。

Windows


Apple から Bonjour for Windows をダウンロードしてインストールすればOK。
iTunes をインストールしていれば自動的に入っているはず。

Saturday, January 5, 2008

"Advanced Rails Recipes" beta book updated with 25 more recipes!

Advanced Rails Recipesにひと月足らずで25の新しいレシピが追加された。
先日の記事What I'v just discovered in Advanced Rails Recipesでは、あんまり面白くなかったと書いたけれど、今回追加されたレシピには興味を惹く引くものが多かった。
追加されたレシピのタイトルは、著者の Mike Clark のブログで参照してください。

また、前回と同様に簡単なメモを...

Skinny Controller, Fat Model


モデルが汚くなるのを犠牲にしてもコントローラをシンブルにすることを自分と同僚で推奨していたが、そのことが "skinny controller, fat model" (もとネタは Jamis Back のブログらしい) という言葉で、いくつかのレシピで言及されているのを見て、「やっぱりそれでよかったんだ」と思った。

caching up with big guys


cache_fu は ActiveRecord::Base.find の結果をキャッシュする。
acts_as_cached には :include => :tags や :ttl => 5.minutes がある。

returning true do
...
end

というコードがあり、 active support に returning というメソッドがあることを知った。

returning [] do |value|
value << "foo"
value << "bar"
end

という使い方もできる。
activesupport/lib/active_support/core_ext/object/misc.rb を見たら with_options もあったことを思い出した。
しかし、こういうよく知られていない、または自前のメソッドを使うとコードがわかりにくくなる。

Creating meaningful relationships through proxies



group.rb:
has_many :users

user.rb:
class User < ActiveRecord::Base
def self.find_men
self.find(:all, :conditions => "sex = 'male'")
end
end

で、 association proxy からも group.users.find_men として利用できることを知った。考えてみれば当然かもしれないが気づかなかった。

Decouple your javascript with Low Pro


lowpro.jsのEvent.createBehavior, Event.addBehavior を使えば javascript をスッキリ書けるかも

Dynamically Updating Cached pages


動的要素のあるページを page cache にしたときにそのダイナミックな部分を ajax で更新するようにはしたことがあるが、部分だけタイムラグが出てしまうが、この方法だと session とは別の cookie に javascript だけでダイナミック部分を補完できる情報を(i.e:ユーザー名)入れておけば javascript で cookie の中身を使って static page の補完ができるというアイデア。

Handling Multiple Models In One Form


Project has_many :tasks などのときに、Project#new_tasks= でコントローラを小さくする手法。この手法も良く使う。

Responding To Remote Capistrano Prompts


Capistrano でリモートサーバーの script/console セッションを操作する方法が書いてある。試してみよう。

Taking Advantage of Master/Slave Databases


リプリケーションしたDBへのクエリを master/slave で自動で振り分ける
masochism plugin の紹介。使えるかもしれない。

Testing HTML Validity


HTML test plugin の紹介。
たぶん常に有効になっているとウザイので、 rake html_validity test のようにして実行したときだけ有効になるようにすると良いかもしれない。