Rails 2.0のRC2がリリースされましたね。正式リリースも間近のようです。

Rails 2.0: Release Candidate 2

After another batch of fixes, tweaks, and buckets of polish, we’ve prepared the hopefully last step before 2.0 can go final: Release Candidate 2. If nothing major pops up, expect the final version to land within the next week or two at the most.

早速、このブログもRails 2.0 RC2にアップデートしてみました。
今まではRC1でしたが、特に問題も無く、すんなりと移行できました。

posted by genki genki on Fri 30 Nov 2007 at 07:03 with 0 comments

acts_as_searchable
is one of the most useful plugins which's enabling us to add a fulltext search feature to our models/resources easily.

Unfortunately, it is lacking an interface to the features of searching by similarity provided by
HyperEstraier.

So I wrote some codes to add an interface to exploit it.
This is
acts_as_searchable_with_similarity.

How to use?

Here is an example.

app/models/article.rb

rails>>
class Article < ActiveRecord::Base
acts_as_searchable
end

Article.similarity_search(target_article, :limit => 5)
<<--

posted by genki genki on Thu 29 Nov 2007 at 23:37 with 0 comments

acts_as_searchable
は、
HyperEstraier
を使って簡単に全文検索を行うことができる、
非常に便利なRailsプラグインです。
しかし、HyperEstraierが提供する類似検索機能を使うインターフェイスが
用意されていないようだったので、類似検索機能を付け足しました。

オリジナルの
acts_as_searchable
に対する差分はこちらにあります。

使い方

まずは、オリジナルと同様に検索対象のモデルに
acts_as_searchableを書き加えます。
必要に応じて適切なオプションを指定してください。

app/models/article.rb

rails>>
class Article < ActiveRecord::Base
acts_as_searchable
<<--

あとは、以下のように類似検索を行うだけです。

rails>>
Article.similarity_search(target_article, :limit => 5)
<<--

ちなみに、このブログの類似記事表示機能でも使用しています。

MIT LICENSE
に基づいて、修正版を再配布します。

  1. このソフトウェアを誰でも無償で無制限に扱って良い。但し、著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載しなければならない。
  2. 作者または著作権者は、ソフトウェアに関してなんら責任を負わない。

修正部分のコードもMIT LICENSEとします。

posted by genki genki on Thu 29 Nov 2007 at 23:08 with 0 comments

SyslogLogger

SyslogLogger is a Logger replacement that logs to syslog.
It is almost drop-in with a few caveats.

SyslogLoggerを使うと、railsのログを syslog に記録するように
する事ができます。

###インストール方法

shell>>
% sudo gem install SyslogLogger
<<--

普通に rubygems としてインストールできます。
続いて、アプリケーションの設定を行います。

config/environments/production.rb

rails>>

SyslogLogger

require 'syslog_logger'
RAILS_DEFAULT_LOGGER = SyslogLogger.new 'appname'
<<--

appnameはアプリケーションを識別する名前に置き換えてください。

さらに、syslogの設定を行います。
rootになって以下の記述を書き加えます。

/etc/syslog.conf

!appname
*.*     /var/log/appname.log

修正が済んだら、空の/var/log/appname.logファイルを作成して
syslogdを再起動します(例えば killall -HUP syslogd

これで、以後は /var/log/appname.log 及び /var/log/syslog
ログデータが書き出されるようになります。

posted by genki genki on Thu 29 Nov 2007 at 07:26 with 0 comments

Hash#sliceが欲しい
をさらに拡張。

指定したキーを取り除いたHashを返すHash#exceptを追加。
併せて、既存のHash#sliceHash#onlyに改名してみました。

hash_ext.rb

ruby>>
class Hash
def only(*args)
args = *args if args[0].is_a? Array
args.inject({}){|hash, key| hash[key] = self[key]; hash}
end

def except(*args)
args = *args if args[0].is_a? Array
args.inject(dup){|hash, key| hash.delete(key); hash}
end
end
<<--

使い方:

ruby>>
cond = params.only :year, :month, :day
ma = MonthlyArchive.find :all, :conditions => cond.except(:day)
<<--

posted by genki genki on Thu 29 Nov 2007 at 03:08 with 0 comments

ドメイン境界を越えてjsで通信する方法。

Introducing CrossFrame, a Safe Communication Mechanism Across Documents and Across Domains

たぶんShootingStarで使ってる方法と同じものだと思う。

posted by genki genki on Wed 28 Nov 2007 at 16:11 with 0 comments
そうじゃないか。
posted by genki genki on Wed 28 Nov 2007 at 06:44 with 0 comments

ので作ってみた。

hash_ext.rb

ruby>>
class Hash
def slice(*args)
args = *args if args[0].is_a? Array
args.inject({}){|hash, key| hash[key] = self[key]; hash}
end
end
<<--

使い方:

ruby>>
conditions = params.slice :year, :month, :day
<<--

posted by genki genki on Wed 28 Nov 2007 at 04:16 with 0 comments

Rails 2.0(RC1)でチェックしてみたところ、以下のような構文で migration
コードの生成時に追加・削除を行うcolumnを指定できるようです。

shell>>
% ./script/generate migration add_fullname_to_users fullname:string
<<--

この結果、生成生成されるコードは以下の通り。

db/migrate/XXX_add_fullname_to_users.rb

rails>>
class AddFullnameToUsers < ActiveRecord::Migration
def self.up
add_column :users, :fullname, :string
end

def self.down
remove_column :users, :fullname
end
end
<<--

ちょっと前まで、add_xxxx_to_yyyy で yyyyテーブルにxxxxカラムを
追加するという感じの挙動をしていたのですが、それは無くなったみたいですね。
まだRC1なので最終的にどういう形に落ち着くか分かりませんが、
なかなかいい感じです。

posted by genki genki on Wed 28 Nov 2007 at 02:08 with 0 comments

今まできちんと動作していなかった、DailyとMonthlyのアーカイブ表示の
実装を修正しました。

記事一覧表示画面の上部に表示されているカレンダーからアクセスできます。

よろしくお願いします。

posted by genki genki on Tue 27 Nov 2007 at 17:44 with 0 comments

Railsのroutes.rbでNamed Routeを利用するときに、
メソッド名の競合などで通常は使えない名前をどうしても
利用したい場合、以下のように記述することで利用できます。

config/routes.rb

rails>>
map.send :method_missing, :touch, 'foo/:id/touch', :action => 'touch'
<<--

メソッドがすでに定義されているため、method_missing
が呼ばれなくなっている状態を無理やり回避しています。

posted by genki genki on Mon 26 Nov 2007 at 15:03 with 0 comments

Railsのプラグインは、簡単に作れるせいか、おかしな、
というか、随分てきとうな名前のものが多いのですが、最近は
一時期流行していたacts_as_xxxable系のプラグインに代わり、
xxx_fuという名前のプラグインが増えてきました。

timezone_fu

  • Timezone conversion with TZInfo as easy as has_timezone :fields => [ :start_datetime, :end_datetime].
  • 美しい世界地図が印象的

enum_fu

  • Make an integer field as an enum typed one

resource_fu

  • A collection of hacks that make nested and polymorphic
    resources less painful.

Bundle-fu

  • CSS/JS asset bundling in 10 seconds or less!
  • Rails-2.0 Readyだ!

mimetype-fu

  • Get the content type / mime type of a file. Great to use with
    attachment_fu or to validate Flash uploads.

Attachment Fu

  • Rewrite of acts_as_attachment
  • Amazon S3も使える

Permalink Fu

  • Create permalinks from attributes

BackgroundFu

  • Threadを使って時間がかかる処理を行う

さて、次に流行するのはどんな名前でしょう。

更新履歴

  • 2007/12/11 BackgroundFuを追加
posted by genki genki on Mon 26 Nov 2007 at 05:49 with 0 comments
記事の引越しから漏れていたのでサルベージ。

zsh用のscript/generateおよびscript/destroyの補完関数です。
以下のスクリプトを.zshrcなどに書いておけば、
./script/generateに続けてTABキーを押す事で
generatorの入力を補完できます。

~/.zshrc

shell>>
_generate () {
if [ ! -f .generators ]; then
./script/generate --help | grep '^ [^ ]: ' | sed 's/[^:]:/compadd/' | sed 's/,//g' > .generators
fi
cat .generators
}

compdef _generate generate
compdef _generate destroy
<<--

RubyGems、Plugin、BuildInの3種類のgeneratorを検出して補完します。
検出動作が重いので、カレントディレクトリにキャッシュファイルを作成して
2度目以降の補完を高速化しています。
generatorを追加した場合など、キャッシュを無効化したい場合は

shell>>
$ rm .generators
<<--

でキャッシュファイルを削除してください。

補完が重くても余計なファイルが生成されるよりはマシ、
という場合はこちらをどうぞ。

shell>>
_generate () {
./script/generate --help | grep '^ [^ ]*: ' | sed 's/[^:]*:/compadd/' | sed 's/\,//g'
}

compdef _generate generate
compdef _generate destroy
<<--

誰かが作らないかなあ、と思って待っていたのですが、
なかなか出て来ないので自分で作りました。
もっと良いものがあったら教えていただけると嬉しいです。

posted by genki genki on Mon 26 Nov 2007 at 05:06 with 0 comments

ORF 2007
で地下展の話を聞いて興味深かったので、
日本科学未来館に行ってきました。

ticket

ボストーク湖
の展示が興味深かったです。
ほかにもいくつか面白いキーワードを採取できました。

それから、お土産店で蛍石と方解石をGet。

蛍石(左)と方解石(右)

rock

どちらの鉱石も、レンダリングアルゴリズムを考える上では、
興味深い光学特性を持っています。

posted by genki genki on Mon 26 Nov 2007 at 04:31 with 0 comments
記事の引越しから漏れていたのでサルベージ。 Generatorプラグインの作り方をメモしておきます。 まずはプラグインの雛形を作ります。 shell-unix-generic>> $ ./script/generate plugin foo <<-- 次にGeneratorプラグインに必要なディレクトリを用意。 shell-unix-generic>> $ mkdir -p vendor/plugins/foo/generators/foo/templates <<-- FooGeneratorクラスの定義ファイルを作成 **vendor/plugins/foo/generators/foo/foo_generator.rb** ruby_on_rails>> class FooGenerator < Rails::Generator::NamedBase def initialize(runtime_args, runtime_options = {}) super ~ 引数・オプションの解釈と初期化 ~ end def manifest record do |m| ~ マニフェスト ~ end end end <<-- マニフェストの書き方は [この辺](http://dev.rubyonrails.org/browser/trunk/railties/lib/rails_generator/generators/components/controller/controller_generator.rb) が参考になります。基底クラスは、Rails::Generator::Baseの派生クラスなら何でもOKです。 続いて、マニフェストから参照するテンプレートファイルをtemplatesディレクトリの中に作ります。テンプレートファイルはERbテンプレートなので、Generatorクラスのコンテクストでrhtmlを書くような感じで記述できます。 以上で完了。Generatorを使うときは以下の通り。 shell-unix-generic>> $ ./script/generate foo <<-- マニフェストの書式を以下にまとめておきます。
**`m.class_collisions( *class_names)`** 生成するクラス名の衝突を検出します。 Generatorで生成する予定のクラス名をすべて列記しておきましょう。 **`m.directory(relative_path)`** RAILS_ROOTからの相対パスで、指定したディレクトリを利用する事を 宣言します。 **`m.template(relative_source, relative_destination, template_options = {})`** Generatorが生成するファイルを宣言します。`relative_source`は、templatesディレクトリからの相対パスでERbテンプレートを指定します。`relative_destination`には生成されるファイルの場所を`RAILS_ROOT`からの相対パスで記述します。 `template_options`には、`:assigns => {:foo => some_thing}` のような感じで、ERbテンプレートから参照可能な値を設定する事ができます。 **`m.readme( *relative_sources)`** helpドキュメントを指定します。指定したファイル群は単純に連続出力されます。 **`m.migration_template(relative_source, relative_destination, template_options = {})`** migrationファイルの生成を宣言します。migrationファイルは、ファイル名の先頭に005_のようなプレフィックスが付くので、専用のメソッドが用意されています。 `relative_destination`は、migrationファイルを配置するディレクトリを、`RAILS_ROOT`からの相対パスで指定します。生成するファイル名は、`template_options[:migration_file_name]` で明示的に指定するか、さもなくばGeneratorの引数から自動的に決定されます。 そのほかの挙動はm.templateと同じです。  **`m.dependency(generator_name, args, runtime_options = {})`** Generatorの依存関係を宣言します。これによってメタジェネレータを記述する事も可能です。素晴らしいですね。 **`m.file(relative_source, relative_destination, file_options = {}) {|sf| ...}`** ファイルのコピーを宣言します。`relative_source`、`relative_destination` はそれぞれ`RAILS_ROOT`からの相対パスです。 `file_options`には、`:chmod`, `:shebang`, `:collision`を指定します。 詳細な挙動については [こちら](http://edgedocs.planetargon.org/classes/Rails/Generator/Commands/Create.html#M004122) を参照のこと。 ブロック引数は、`relative_source`で指定したファイルが何らかのテンプレートファイルであるときに、テンプレートを展開する処理を記述します。そうでない場合は省略可能です。
より詳細な情報が必要な場合は、 [Rails::Generator::Commands::Createクラスのドキュメント](http://edgedocs.planetargon.org/classes/Rails/Generator/Commands/Create.html) 及び [Createクラスの基底クラスであるRails::Generator::Commands::Baseのドキュメント](http://edgedocs.planetargon.org/classes/Rails/Generator/Commands/Base.html) をご覧ください。 **更新履歴** * 2006/08/10 マニフェストの書き方を最後の方にまとめておきました。 * 2007/11/22 記事の移行からもれていたのでサルベージ
posted by genki genki on Thu 22 Nov 2007 at 05:43 with 0 comments
This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/178

HyperEstraier
は、全文検索エンジンです。Ruby on Railsから利用する場合は、acts_as_searchableを利用すると、非常に簡単にWebサービスに検索機能を追加することができます。

今回は、HyperEstraierのP2P連携機能を使ってクラスタリングを行う手順を紹介します。

まず、クラスタリングを行う全てのPCに、
通常の手順でHyperEstraierをインストール
します。パッケージマネージャを使う事もできますが、今回はソースからインストールする事にします。

インストールが済んだら、HyperEstraierを初期化して起動します。以下では、/usr/local/hyperestraier以下に環境を構築しています。

shell-unix-generic>>

estmaster init /usr/local/hyperestraier

estmaster start -bg /usr/local/hyperestraier

<<--

起動したら、ポート1978にアクセスし、動いていることを確認します。
続いてWebインターフェイスからノード間のリンクを作成します(もちろん、あらかじめノードを作成しておく必要があります。)

リンクの作成は、ノード編集画面から行います。

例)
http://search-1.com:1978/master_ui?action=10&name=nodename

ノード編集画面の一番下のlist of linksに以下のように、「{{!}}」で区切って別なサーバのノードを登録します。

http://search-2.com:1978/node/nodename{{!}}label{{!}}1000

上記は、search-2.com上のnodenameというノードに対して、labelというラベルでリンクを作成しています。1000というのは信頼度で、検索結果の順位に影響します。1台目から2台目へのlinkの設定が済んだら、2台目から1台目に逆方向にリンクを張ります。

以上でクラスタリングは完了です。
実際に検索を行うときは、メタ検索のdepthを1以上に指定する必要があります。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/178
posted by genki genki on Thu 22 Nov 2007 at 04:48 with 0 comments
記事の引越しから漏れていたのでサルベージ。

Ruby on Railsを使ってある程度大きめのアプリケーションを作るようになると、ごく稀に「Lost connection to MySQL server during query」というエラーが発生するようになる事があります。

この問題については、yuguiさんの記事
Lost connection to MySQL server during query
に詳しいです。

結局のところ、はっきりとした解決策も見つからず、ごく稀なので放置気味になっていたのですが、先日解決策を見つけたので改めて紹介します。

解決策:

mysql_retry_lost_connectionというrubygemを使うことで、コネクションのLostが発生した場合に、自動的に再接続を試みるようにActiveRecordの挙動を修正することが出来ます。

詳細はこのGemの作者のTylerさんの記事
Saying goodbye to lost connections in Rails」で説明されています。

使い方:

# sudo gem install mysql_retry_lost_connection

を行い、config/environment.rbの中でrequire 'mysql_retry_lost_connection'をすればOK。
rails
2日ほど使ってみたところ、このGemを導入してから一度もLostConnectionのエラーが発生しなくなりました。このGemが効果を表さない場合もあると思いますが、Lost Connectionでお悩みの方には朗報ではないかと思います。

See Also

posted by genki genki on Wed 21 Nov 2007 at 13:30 with 0 comments
記事の引越しから漏れていたのでサルベージ。

RubyInsideで紹介されていたUsing Omnigraffle to visualise Rails model associationsに触発されて、 Model同士の関係をグラフで表示するプラグインを作ってみました。

こんな感じのグラフを表示します。

使い方は、まずプラグインをインストールします。

$ ./script/plugin install http://svn.labs.drecom.jp/rails/plugins/trunk/model_graph
このプラグインはControllerジェネレータになっているので、次のように ModelGraphを表示するControllerを生成します。
$ ./script/generate model_graph
これによってModelGraphControllerが生成されるので、あとは'/model_graph'にアクセスすれば、上図のようなグラフが表示されます。もちろんGraphVizに依存しているので、事前にインストールしておく必要があります。

オリジナルの実装に加えて、app/models以外の場所に存在するすべてのModelの関係を表せるように改良してあります。

デフォルトのURLマッピングを削除している場合は、routes.rbにmodel_graphコントローラのindexアクションにマップするURLの記述を追加してください。

map.connect 'model_graph', :controller => 'model_graph'
ジェネレータプラグインなので、不要になったら
$ ./script/destroy model_graph
を実行すれば削除できます。

デフォルトではPNG形式の画像が出力されますが、'/model_graph?format=svg'のようにフォーマットを指定する事で、GraphVizがサポートするpng、gif、jpeg、svgの4種類の形式で出力する事ができます。

posted by genki genki on Wed 21 Nov 2007 at 13:22 with 0 comments
記事の引越しから漏れていたのでサルベージ。 [secondlifeさんの記事](http://d.hatena.ne.jp/secondlife/20061010/1160453355) に反応して後で書こうかなあと思っていたら、大分時間がたってしまいましたが、めげずに書いてみます。
1. p/pp
こちらはRailsに限らず良く使われている方法ですが、RailsではWebサーバをフォアグラウンドプロセスとして立ち上げた状態で使う感じになります。 pre>> $ ./script/server <
2. logger.debug
さて、続いてlogger.debugを使う方法です。 pre>> logger.debug "something interesting information" <
>
$ tail -f log/development.log
<
3. script/console
script/consoleは、実行時にデータベースの中身がどうなっているかを知りたい時に非常に便利です。script/consoleコマンドを実行すると、Railsの環境を読み込んだ状態でirbが立ち上がるので、ActiveRecordを使ってfindしたりcreateしたりdestroy_allしたり、好きなようにDBをいじる事ができます。本当に素晴らしい機能ですね。
4. script/breakpointer
script/consoleはとても素晴らしいのですが、アクション実行中のsessionの状態を調べたりするのには使えません。そんな時は、script/breakpointerを使う事ができます。 pre>> $ ./script/breakpointer <
>
class FooController < ApplicationController
  def bar
    # something
    breakpoint
    # something
  end
<
5. better rails debugger
script/breakpointerはとても便利ですが、ステップ実行が出来ないという問題があります。 実際にステップ実行がどうしても必要という場面はあまり無いのですが、あればあったほうが便利ですね。そんな時は、ruby-debugというGemを使います。 これは前回のRails勉強会のときにyuguiさんから教えていただいた方法なのですが、まずはruby-debugをインストールします。 pre>> # gem install ruby-debug <
>
class FooController < ApplicationController
  def bar
    # something
    debugger
    # something
  end
<
6. test/autotest
Ruby on Railsでは、テスト用のフレームワークがはじめから使える状態になっています。 テスト駆動開発では、テストを書いてから実装を書きますが、適当な動作検証用のコードをテストとして書くことで、デバッグに使う事もできます。この際、毎回テストをrakeコマンドから実行するのは時間が掛かるので、ZenTestのautotestを使うのがお勧めです。 autotestを使うと、編集されたファイルに関連するテストだけを実行してくれるので、rakeコマンドを実行するよりも軽快なレスポンスが得られます。さらにredgreenを併用すると気分良くデバッグを行う事ができるのでお勧め。
7. tail -f log/development.log&; autotest
最後に、僕が今使っている方法を紹介します。 開発用とは別に一つターミナルを立ち上げて、RAILS_ROOTで以下のコマンドを実行。 pre>> $ tail -f log/development.log&; autotest <
というわけで、Railsでデバッグを行う方法の紹介でした。
posted by genki genki on Wed 21 Nov 2007 at 12:39 with 0 comments
記事の引越しから漏れていたのでサルベージ。

RubyGems パッケージの作り方 - rubyforge 登録まで

僕はまだRubyForgeにGemを登録した事がないので、secondlifeさんの記事はとても参考になりました。蛇足感もありますが、多様性は善という事で、HoeというGemを使ったもう一つのRubyGemsパッケージの作り方を紹介します。

Hoeは、Seattle.rb Projects
による一連のプロジェクトの中の一つで、やはりnewgemと同じようにRubyGemsの作成を簡単にしてくれるGemです。

Hoeを使ってGemを作る流れは、

  1. sowコマンドでGemの雛形を生成
  2. 雛形を元にGemを作成

という感じで、非常に簡単です。具体的に簡単なGemを作る方法を紹介します。

まずはHoeをインストールしましょう。

# gem install hoe --include-dependencies

そしてGemの雛形を生成します。

shell-unix-generic>>
$ sow sample
creating project sample
... done, now go fix all occurances of 'FIX'

sample/Rakefile:9: # p.summary = 'FIX'
sample/README.txt:2: by FIX
sample/README.txt:3: FIX
sample/README.txt:7:FIX
sample/README.txt:11:* FIX
sample/README.txt:15: FIX
sample/README.txt:19:+ FIX
sample/README.txt:23:+ FIX
sample/README.txt:29:Copyright (c) 2006 FIX
<<--

とりあえずこのFIXというところをカスタマイズすればOKという親切ぶりです。
そしてさらに、次のようなRakeタスクが生成されます。

shell-unix-generic>>
$ rake -T
(in /home/takiuchi/sample)
rake announce # Generate email announcement file and post to rubyforge.
rake audit # Run ZenTest against the package
rake check_manifest # Verify the manifest
rake clean # Clean up all the extras
rake clobber_docs # Remove rdoc products
rake clobber_package # Remove package products
rake debug_gem # Show information about the gem.
rake default # Run the default tasks
rake docs # Build the docs HTML Files
rake email # Generate email announcement file.
rake install # Install the package. Uses PREFIX and RUBYLIB
rake install_gem # Install the package as a gem
rake multi # Run the test suite using multiruby
rake package # Build all the packages
rake post_news # Post announcement to rubyforge.
rake publish_docs # Publish RDoc to RubyForge
rake redocs # Force a rebuild of the RDOC files
rake release # Package and upload the release to rubyforge.
rake repackage # Force a rebuild of the package files
rake ridocs # Generate ri locally for testing
rake test # Run the test suite. Use FILTER to add to the command line.
rake uninstall # Uninstall the package.
<<--

なんとも魅力的な名前のタスク達ではないでしょうか。
rakeコマンドを打つだけでRubyForge上でのいろんな作業が出来てしまいそうです。

そのほか細かいところは同じなので、secondlifeさんの記事をご参照ください。

posted by genki genki on Wed 21 Nov 2007 at 12:36 with 0 comments

LiveConsole

昔、Rails勉強会の懇親会で
yuguiさん
と話した、走り続けるプログラムの事を思い出した。

  • 起動や停止するという概念が無いプログラム
  • 自己複製による並列処理
  • 蓄積したバグによる老化と死、世代交代

そして、それを記述するための言語。

継承、遺伝、進化。

posted by genki genki on Wed 21 Nov 2007 at 11:25 with 0 comments

ブラウザ以外のUserAgentからRailsアプリケーションにリクエストを送る場合、Railsが管理しているsessionの仕組みとは別に、自分でセッションをセットアップしたくなる事があります。

そのような場合は、たとえばクエリパラメータからsession_idを渡したりするのですが、GET methodで受け渡したsession_idからRailsのsessionを再現するためには、以下のように記述します。

ruby_on_rails>>
FooController < ApplicationController
session :off, :if => (proc do |req|
return false unless req.parameters[:action] == 'bar'
if req.parameters[:session_id]
@original_session_options = req.session_options
req.session_options[:session_id] = req.parameters[:session_id]
end
false
end)
prepend_before_filter :only => 'bar' do
if @original_session_options
@original_session_options[:session_id] = nil
end
end
<<--

before_filterを使っていないのは、before_filterでは
Railsのsession処理に間に合わないためです。

更新履歴

  • 2007/11/20 不具合があったため内容を修正しました
posted by genki genki on Tue 20 Nov 2007 at 15:42 with 0 comments

Rails勉強会@東京#02-24

Genki Takiuchi

Recent Situation:

  • Founded small company.
  • Moved to Shindaita from Ebisu.
  • Became slightly familiar with MAC.
  • And also with Rails 2.0

Favorite Things:

  • C/C++ Template, JavaScript, Ruby.
  • Thinking algorithm, Rendering (CG) and 3D.
  • Vim7, Zsh, GNU screen, rails.vim, ZenTest.

Thank you!

posted by genki genki on Sun 18 Nov 2007 at 08:58 with 0 comments

画面の内容に合わせて、必要なJavaScriptやStyleSheetをincludeする場合、
以前紹介した
content_forを使うのが便利ですが、
画面内で何度も呼び出される partial のなかに記述したりすると、
呼び出された回数分だけ include されてしまったりして不便です。

そこで、画面内で一回だけ content_for を実行するためのプラグイン、
content_for_once を作りました。こちらに置いてあります。

使い方。まずはプラグインをインストールします。

shell-unix-generic>>
% ./script/plugin install https://svn.s21g.com/public/rails/plugins/content_for_once/
<<--

あとは、Viewから以下のようにして呼び出します。

html_rails>>
<% content_for_once :head do %>
<%= javascript_include_tag 'iepngfix' %>
<% end %>
<<--

これで、このコードが実行されたときに、一度だけJavaScriptが
includeされるようになります。

posted by genki genki on Sun 18 Nov 2007 at 05:05 with 0 comments

Ultraviolet
によるシンタックス・ハイライトに対応しました。

書式は以下のような感じです。

ruby>>
def foo
  bar
end
<<--

レンダリング結果は以下のとおり。

ruby>>
def foo
bar
end
<<--

posted by genki genki on Sun 18 Nov 2007 at 04:32 with 0 comments

会社設立や、それに伴う環境の変化への対応などのため、しばらく開発がとまってしまっていた
ShootingStar
ですが、ipod touch&iphoneへの対応作業をほぼ完了いたしました。

DEMO: http://www.cocktail-party.jp/

screen shot

もうしばらくコードの整理をしてから、version 3.2.5 をリリースいたします。

よろしくお願いいたします。

posted by genki genki on Sat 17 Nov 2007 at 19:05 with 0 comments

Core Services社が提供している
DebugBar
Companion.JS
を使って、IE6のデバッグ環境を改善してみた。

ScreenShot1

DebugBarは、ツールバー(DeskBand)とサイドバー(InfoBand)を使ったIE拡張で、DOM Inspector的な機能がある。Companion.JSは、CommBandを使ったIE拡張で、Script Console機能を持っている。

IEのJavaScriptデバッグには、本当に難儀していたので有難い。

posted by genki genki on Sat 17 Nov 2007 at 09:57 with 0 comments

以前、ログをトレースしながらautotestを走らせる方法を紹介しましたが、
今回はさらにその方法を拡張して、script/consoleも同時に実行してしまう
方法を紹介します。

ちなみに以前紹介した方法は、こんな感じでした。

% tail -f log/development.log &
% autotest

tail -f log/development.log &でloggerの出力をバックグラウンドで補足しつつ、フォアグラウンドではautotestを実行しています。

今回は、autotestもさらにバックグラウンドで起動させて、
フォアグラウンドで./script/consoleを実行させるのですが、
一つ問題があります。

autotestは、migrationの実行などでDBの中身が変わった場合など、
Ctrl+CでINTを送ってリロードさせる必要があるのですが、
バックグラウンドプロセスにしてしまうと、Ctrl+Cでリロード
できなくなってしまいます。

そこで、autotestのリロードを script/consle の中から行えるように
するプラグインを作りました。

インストール方法は、通常のRailsプラグインと同様です。

% ./script/plugin install http://svn.s21g.com/public/rails/plugins/trident/

使い方は、モニタリング用のコンソールから以下のRakeタスクを実行します。

% rake trident

すると、tail -f log/development.logautotestが実行され、
script/consoleが立ち上がります。

この状態で、autotestをリロードさせる場合、script/consoleから

> Trident.reload

を実行すればOKです。

終了するときは、普通にscript/cosoleexitすると、生成された子プロセスと一緒に終了します。

posted by genki genki on Fri 16 Nov 2007 at 10:54 with 0 comments

こちら
で、ExceptionNotifierプラグインのテンプレートに関するバグの報告が出ていました。

Plugins - Exception Notifier

Brett Neumeier 12 Oct 2007

In ruby 1.8.6p111, rendering the _environment.rhtml plugin fails with "TemplateError: flag after width". This is fixed if you change the string "%-s" to "%-s" on line three of the template.

Chris 18 Oct 2007

This is the correct string: "%-*s:"

具体的には、views/exception_notifier/_environment.rhtml の3行目を次のように修正すればOKのようです。

views/exception_notifier/_environment.rhtml

<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
<% @request.env.keys.sort.each do |key| -%>
* <%= "%-*s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %>
<% end -%>

手元の環境(ruby-1.8.6 p36/Rails-1.99.0)では、これで問題なく動作するようになりました。

posted by genki genki on Thu 15 Nov 2007 at 05:11 with 0 comments

Railsのプラグインは非常に便利な仕組みなのですが、pluginのテスト
とうまく付き合うにはちょっと工夫が必要です。

plugin用に書かれているテストは、二通りの方法で実行される可能性があります。

  1. plugin ディレクトリの中で rake コマンドた実行された場合
  2. RAILS_ROOT から rake test:plugins が実行された場合

いくつかのプラグインは、上記の片方のケースのみを想定して
test が書かれている場合があり、想定されていないケースからテスト
が実行された場合、多くは沢山のエラーを出すようになります。

このような場合、プラグインディレクトリのRakefileに手を加えて、
呼び出し元に応じて処理を分けたりすれば、一見うまくいきそうですが、
そう簡単にはいきません。

Railsの test:plugins の仕組みは、プラグインディレクトリの
Rakefileを参照せずに、直接 test ディレクトリの中身を実行する
からです。

この挙動はあまり良くないと思うのですが、とりあえず、
rake test:plugins から実行するとエラーを出すプラグインの
テストディレクトリの名前を plugin_test 等に変更して、
プラグインのRakefileを以下のように書き換えることで回避できます。

Rakefile

ruby>>
desc 'Test the acts_as_taggable_on_steroids plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'plugin_test/**/*_test.rb'
t.verbose = true
end
<<--

これによって、上記 1 のケースでは正常に動作し、2 のケースではSkipされるため、エラーの山を見ることから逃れられます。

posted by genki genki on Thu 15 Nov 2007 at 02:14 with 0 comments

Rails 2.0 RC1を使うようになったせいかどうかはわからないのですが、何故か僕の環境では acts_as_taggable_on_steroids のplugin testでFailureが一つ出るようになっていたので、修正してみました。

こんなエラーが出る

  1) Failure:
test_tag_destroyed_when_unused(ActsAsTaggableOnSteroidsTest)
    [./test/abstract_unit.rb:81:in \`assert_difference'
     /home/takiuchi/blog/vendor/rails/activerecord/lib/active_record/\
callbacks.rb:309:in \`each_with_index'
     ./test/abstract_unit.rb:80:in \`each'
     ./test/abstract_unit.rb:80:in \`each_with_index'
     ./test/abstract_unit.rb:80:in \`assert_difference'
     ./test/acts_as_taggable_test.rb:328:in \`test_tag_destroyed_when_unused']:
<5> expected but was
<6>.

修正箇所は以下のとおり。

vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb (L167-184)

ruby>>
def save_tags
return unless @tag_list

  new_tag_names = @tag_list - tags.map(&:name)
  old_tags = tags.reject { |tag| @tag_list.include?(tag.name) }

  self.class.transaction do
    tags.delete(*old_tags) if old_tags.any?
    # added by takiuchi to make all tests green.
    old_tags.each{|tag| tag.destroy} if Tag.destroy_unused
      new_tag_names.each do |new_tag_name|
      tags << Tag.find_or_create_with_like_by_name(new_tag_name)
    end
  end

  true
end

<<--

Tag.destroy_unused が指定されている場合、old_tagsdestroy
するようにしました。これで上記の Failure は出なくなりました。

posted by genki genki on Thu 15 Nov 2007 at 01:47 with 0 comments

BlueClothのソースをitemのbodyとして配信していましたが、
レンダリング結果を配信するように変更しました。

よろしくお願いします。

posted by genki genki on Wed 14 Nov 2007 at 15:06 with 0 comments

yieldcontent_for の使い方の紹介。

Railsを使っていてありがちなのが、layouts/application.rb で共通レイアウトテンプレートを使っているときに、画面ごとに <head> の中身を変えたいという事。

そんなときは yieldcontent_for を使えばOK。

layouts/application.html.erb

<head>
  (- - snip - -)
  <%= yield :head %>
</head>

foos/bar.html.erb

<% content_for :head do %>
  <%= javascript_include_tag 'iepngfix' %>
<% end %>

こんな感じに、画面ごとに <head> に追加したい項目を書くことができます。

また、 content_for は、何度呼び出してもOKです。呼び出した順に追記されていきます。

<head> の中身のほかにも、サイドバー等の共通レイアウトにも使えますね。

posted by genki genki on Wed 14 Nov 2007 at 14:46 with 0 comments

すんなり完了すると思ったらちょっと引っかかったのでメモ。

debian (etch) をほぼデフォルト設定で入れていたので、こんな感じに486系のkernelが入っていた。

/boot/grub/menu.lst

title           Debian GNU/Linux, kernel 2.6.18-5-486
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.18-5-486 root=/dev/sda1 ro
initrd          /boot/initrd.img-2.6.18-5-486
savedefault

これが実は曲者で、cat /proc/meminfo すると

HighTotal: 0 kB
HighFree: 0 kB

HighMemを認識してくれていない。
今回はメモリを1Gから2Gに増設したのだが、1G分しか認識してくれなかった。

そこで、686系のkernelにする事にした。

# apt-get update
# apt-get install kernel-image-2.6-686

これで再起動すると…

/proc/meminfo

HighTotal:     1114048 kB
HighFree:       692068 kB

無事に認識。ほ。

posted by genki genki on Tue 13 Nov 2007 at 06:29 with 0 comments
13th Tue

script/kill

RailsでWebサービスの開発を行っていると、Webサーバとfcgiプロセスをまとめて停止させたくなる事が度々あります。そんな時のために、次のようなスクリプトを書いて使っています。

script/kill

./script/process/reaper -a kill
PID=`cat tmp/pids/lighttpd.pid`
kill -9 $PID

fcgiプロセスだけ再起動させたい場合は、Rails謹製の script/process/reaper -a graceful でOKですね。

posted by genki genki on Tue 13 Nov 2007 at 01:20 with 0 comments

地味に欲しかった機能がいつの間にか実装されていた。

takiuchi% rake -T db:create                                  [~/test]
(in /home/takiuchi/test)
rake db:create      # Create the local database defined in config/database.yml for the current RAILS_ENV
rake db:create:all  # Create all the local databases defined in config/database.yml

これで rake db:create:all と打てばdatabase.ymlに記述されているデータベースが作成されるわけですね。

posted by genki genki on Mon 12 Nov 2007 at 15:56 with 0 comments

topコマンドは、通常CPUの使用率が高い順にプロセスを表示しますが、topコマンドを実行した状態で「Shift+M」を押すと、メモリの使用率が高い順に表示するようになります。メモリ消費量が多いプロセスを特定したい時に便利ですね。

元に戻したい場合は、「Shift+T」を押せばOK。ほかにも以下のような機能があります(topコマンド実行時に「h」キーを押せば表示されます)

  Z,B       Global: 'Z' change color mappings; 'B' disable/enable bold
  l,t,m     Toggle Summaries: 'l' load avg; 't' task/cpu stats; 'm' mem info
  1,I       Toggle SMP view: '1' single/separate states; 'I' Irix/Solaris mode

  f,o     . Fields/Columns: 'f' add or remove; 'o' change display order
  F or O  . Select sort field
  <,>     . Move sort field: '<' next col left; '>' next col right
  R,H     . Toggle: 'R' normal/reverse sort; 'H' show threads
  c,i,S   . Toggle: 'c' cmd name/line; 'i' idle tasks; 'S' cumulative time
  x,y     . Toggle highlights: 'x' sort field; 'y' running tasks
  z,b     . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')
  u       . Show specific user only
  n or #  . Set maximum tasks displayed

  k,r       Manipulate tasks: 'k' kill; 'r' renice
  d or s    Set update interval
  W         Write configuration file
  q         Quit
          ( commands shown with '.' require a visible task display window )
posted by genki genki on Mon 12 Nov 2007 at 00:58 with 0 comments

MH (Metropolis Hastings) アルゴリズムの拡張。

The Multiple-Try Method and Local Optimization in Metropolis Sampling

Jun S. Liu, Faming Liang, Wing Hung Wong
Journal of the American Statistical Association, Vol. 95, No. 449 (Mar., 2000), pp. 121-134
doi:10.2307/2669532

なかなか楽しそう。

posted by genki genki on Sun 11 Nov 2007 at 07:47 with 0 comments

Rails 2.0: Release Candidate 1

We’ve been taking our sweet time, but now it really is almost there. We’ve just pushed new beta gems to gems.rubyonrails.org and created the rel_2-0-0_RC1 tag. So this is shaping up to be the last chance to raise concerns for Rails 2.0 before we go final in oh-so-shortly.

早速このblogをRails-2.0 RC1 (r.8125)仕様にしてみましたが、もともとEdge Rails (r.7357) で動いていたので、特になにも修正をしなくても移行できました。

詳しい情報は、諸橋さんが
こちら
にまとめてくださっています。

posted by genki genki on Sat 10 Nov 2007 at 10:12 with 0 comments

友人の藤田さんが主催しているレンダリング・アルゴリズムのイベント、
SBR 2007 観覧会」が本日恵比寿にて開催されるので、参加してきます。

今年も様々な論文が出ていますが、個人的に気になっているのは、Benjamin Segoviaによる2つ

Eric VeachのMLTに感銘を受けたクチなので、Multiple-Try MHに興味があります。

cmlt

posted by genki genki on Sat 10 Nov 2007 at 09:56 with 0 comments

だいぶ前に少し試したきり放置していたのだけれど、このところ知人の間で急速に広まっている気がします。

この勢いは、Twitterが出始めた時に似たものを感じますね。

ちなみに僕のページはこちらです。

日比さんが会社のページも作ってくれた。

posted by genki genki on Thu 8 Nov 2007 at 23:47 with 0 comments

acts_as_taggable_on_steroids
はacts_as_taggableを強化したRailsプラグインで、非常に便利なので愛用しています。

しかし、find_tagged_withメソッドで OR を含む :conditions を指定すると、SQLの演算順序の問題で挙動がおかしくなります。
この問題を修正するには、以下のようにpluginコードを書き換えればOKです。

acts_as_taggable_on_steroids/lib/acts_as_taggable.rb

    def find_options_for_find_tagged_with(tags, options = {})
      tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags)
      options = options.dup

      return {} if tags.empty?

      conditions = []
      #conditions << sanitize_sql(options.delete(:conditions)) if options[:conditions]
      if options[:conditions]
        conditions << "(#{sanitize_sql(options.delete(:conditions))})"
      end

要は、オリジナルの :conditions を括弧で括って演算順序の問題が起きないようにしているわけですね。

posted by genki genki on Mon 5 Nov 2007 at 17:07 with 0 comments

Railsの設定は、config/environment.rbのなかで、

Rails::Initializer.run do |config|
  # Settings in config/environments/* take precedence over those specified here
  config.log_level = :debug

というような感じに記述します。

アプリケーション側からここで設定した値を参照したいという場合に、その方法が提供されている気がしたので、Rails::Initializerのソースを探してみたのですが、そのような手段は用意されていないようでした。

Railsのコアを書き換えるプラグインを書こうかと思ったのですが、ふと以下のように書けば問題が解決することに気がつきました。

Rails::Initializer.run do |config| $rails_config = config

あとはどこからでも、グローバル変数の$rails_configを介して、Railsの設定情報にアクセスすることが出来ます。

posted by genki genki on Mon 5 Nov 2007 at 16:27 with 0 comments

まだ開発中の機能が多いですが、ひとまずよろしくお願いします。

###画面遷移の仕様

  • ログインするとhome画面(LifeLogを表示・管理)に移動する
  • homeでは、左上のパンくずリストが s21g :: home となる
    • s21g は root (記事一覧画面)に移動する
  • root では、左上のパンくずリストが something new and exciting となる
    • これをクリックすると、ログイン状態では home に移動する
    • 非ログイン状態では、root のまま移動しない
  • /:author は、そのauthorの記事一覧画面に移動する
posted by genki genki on Sat 3 Nov 2007 at 04:47 with 0 comments
Contents rssrss
光ファイバーを二次元振動させて走査するAR用ディスプレイ
因果の取り違え
Swift2's defer for CoffeeScript
mongodb-3.0からcreateIndexのdropDupsが無くなったらしい
mongodb-3.0以降のWiredTigerの設定を動的に変更する方法
一般楕円の高速生成アルゴリズムへの道標
farro mantecatoのレシピ
Droonga関連の記事のまとめ
RuntimeErrorの特定のメッセージに限定してrescueする方法
jQueryでscriptタグを実行せずにappendする
Tags
railstipspluginお知らせblogbuggemrubysearchtestthoughtscgcometdebugnewsreportutilsalgorithmbugfixcluster
Comments rssrss
https://www.oyeanuncios.com/profile/margueritecava https://www.oyeanuncios.com/profile/margueritecava: Hat jemand Tipps gegen die leichte Übelkeit in der... 04/17 23:02
https://athworldproperties.com/author/deangelonewhou/ https://athworldproperties.com/author/deangelonewhou/: Mein Stoffwechsel fühlt sich zum ersten Mal seit J... 04/17 23:00
https://hyperharmony.com/author-profile/shannaminifie/ https://hyperharmony.com/author-profile/shannaminifie/: Endlich ist dieses ständige „Food Noise“ im Kopf k... 04/17 22:49
https://www.legnostyle.ru/catalog/mebel/spalni/sp-3.html https://www.legnostyle.ru/catalog/mebel/spalni/sp-3.html: Мебель из Германии славится на весь мир своими изы... 04/16 15:20
https://slon8.at-slon6.cc https://slon8.at-slon6.cc: Superb, what a webpage it is! This weblog presents... 04/15 21:27
https://wikzaim.ru/ https://wikzaim.ru/: Если деньги нужны срочно нет желания тратить время... 04/15 18:58
https://severlight.su:443/bitrix/redirect.php?goto=https://puertadelsolsanblas.com.ar/3-super-hot-chillies-slot-spicy-reels-and-sizzling-wins/ https://severlight.su:443/bitrix/redirect.php?goto=https://puertadelsolsanblas.com.ar/3-super-hot-chillies-slot-spicy-reels-and-sizzling-wins/: I was curious if you ever thought of changing the ... 04/15 16:00
https://tkoutlet.co.kr https://tkoutlet.co.kr: Hi, I do think this is an excellent web site. I st... 04/15 15:25