2008/08/29

Rails で、アプリケーションから ER図 を生成できる RailRoad を試してみる



Rails には、アプリケーションのモデル・コントローラの内容や関係が記述されたクラス図を、リバースエンジニアリングして生成してくれる RailRoad という便利なツールがあります。


設計は軽くすませて、すぐにプログラミングしていくことが多い Rails アプリケーションですが、全体像を把握したい場合や、他の人に見せたい場合などは、こういうツールがあると便利ですね。


というわけで、実際に使ってみました。


インストール


Graphviz をまずはインストール


railroad をインストール


gem install railroad

Rake タスクとして実行できるようにする


lib/task/diagrams.rake
namespace :doc do
namespace :diagram do
desc "Generate Model diagrams."
task :models do
# SVG
sh "railroad -i -l -a -m -M | dot -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/models.svg"
# PNG
sh "railroad -i -l -a -m -M | dot -Tpng > doc/models.png"
end

desc "Generate Controller diagrams."
task :controllers do
# SVG
sh "railroad -i -l -C | neato -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/controllers.svg"
# PNG
sh "railroad -i -l -C | neato -Tpng > doc/controllers.png"
end
end
desc "Generate Model and Controller diagrams."
task :diagrams => %w(diagram:models diagram:controllers)
end

クラス図の生成


rake doc:diagrams

すばらしいですね。

2008/08/28

Rails で migration 時に、Column Comment を設定する

Railsで、マイグレーション作成時に、カラムにコメントを設定し、それをデータベースに設定する ColumnComments という便利なプラグインがあります。

というか、標準では設定できないんですね・・・。


インストールは次の通りです。



  1. こちらより、ZIPファイルをダウンロード

  2. 解凍して column_comments ディレクトリを vendor/plugins へコピー


使い方は、マイグレーション時に次のように記述します。


Example migration:

def self.up
create_table "users" do |t|
t.column "first_name", :string, :comment => "The member's given name."
end

column_comment "tags", "id", "The unique ID of any tag in the system."
end

そしてさらに、テーブルの情報を model と fixture にコメントとして書き込んでくれる annotate_models プラグインもバンドルされています。が、 annotate_models.rb が古いので、こちらは本家のものと置き換えて、コメントを表示するように修正します。


ついでに、 annotate_modelsにindexの情報を付加する - Hello, world! - s21g を参考に、インデックス情報もつけちゃいます。


vendor/plugins/column_comments/lib/annotate_models.rb - self.get_schema_info
  def self.get_schema_info(klass, header)
info = "# #{header}\n#\n"
info << "# Table name: #{klass.table_name}\n#\n"

# index info by http://blog.s21g.com/articles/318
indices = {}
klass.connection.indexes(klass.table_name).each do |index|
index.columns.each do |column_name|
indices[column_name] ||= []
indices[column_name] << "#{index.name}"
indices[column_name].last << "(unique)" if index.unique
end
end

max_size = klass.column_names.collect{|name| name.size}.max + 1
klass.columns.each do |col|
attrs = []
attrs << "default(#{quote(col.default)})" if col.default
attrs << "not null" unless col.null
attrs << "primary key" if col.name == klass.primary_key
if index = indices[col.name]
attrs << index.join(' ')
end

col_type = col.type.to_s
if col_type == "decimal"
col_type << "(#{col.precision}, #{col.scale})"
else
col_type << "(#{col.limit})" if col.limit
end
info << sprintf("# %-#{max_size}.#{max_size}s:%-15.15s %s", col.name, col_type, attrs.join(", ")).rstrip
info << "\n"
# column comment
unless col.comment.blank?
info << "# #{col.comment}"
info << "\n"
end
end

info << "#\n\n"
end

使い方は、次の Rake タスクを実行します。


rake annotate_models

これでもう、テーブルのカラム名を調べるためにデータベースを見る必要はなくなりそうです。

2008/08/27

Rails で Database から Fixture を抽出したい

Rails で、データベースから yaml(やむる) 形式のフィクスチャを抽出するには、ar_fixtures が有名です(手元の Ruby on Rails 逆引きクイックリファレンス Rails 2.0対応 でも紹介されています)。


ですが、実際使ってみると、日本語(UTF8)がうまく表示されなかったり、項目の並びが適当だったりと、あまりよろしくありませんでした。


そこで、データベースからテストフィクスチャを抽出する(to_yaml 不使用) - Rails で行こう! - Ruby on Rails を学ぶ で紹介されている Rake タスクを使うとばっちりうまくいきます。



ar_fixtures は内部的に to_yaml というメソッドを使っていて、これが UTF-8 の文字列をうまく扱えない。そこで、



日本語をto_yamlするとエンコードされてしまう問題を安直な方法で解決する


to_yamlでUTF-8な日本語がbinaryになってしまう問題を回避するRailsプラグイン


みたいな hack が必要になってくる。


そんなわけで、Chad Flower「Rails レシピ」のレシピ41「生データからのテストフィクスチャの抽出」(p155) のソースコードをベースに次のような Rake タスクを作ってみた。to_yaml は使ってないので、UTF-8 文字列にまつわる頭痛とも無縁だ。興味があれば、使ってみてほしい。



参考:データベースからテストフィクスチャを抽出する(to_yaml 不使用) - Rails で行こう! - Ruby on Rails を学ぶ


2008/08/26

Aptana RadRails で test_helper.rb の LoadError が発生する



Edge Rails (2.1.0) と、Aptana RadRails (1.0.3.200807071913NGT)の環境下で、ツールバー上のテストボタンでユニット・テストの実行をすると、以下のエラーが発生します。


c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- test_helper (LoadError)

コマンドでのテストは問題ないので、「rake test:units」とすればいいのですが、次のようにすれば解決できます。



There is an open issue on the Aptana issue tracker, but it doesn’t seem to be resolved yet.  Some people have suggested prefixing your requires with the test directory when requiring the test_helper file at the start of your test files -but I don’t think that’s a good solution, especially if you’re working with multiple developers.  Frustrated by not getting my daily green bar fix, I found this work-around:


  1. From the Eclipse Preferences option, choose Ruby | Installed Interpreters

  2. Select your interpreter (I use the Standard VM default interpreter named usr) and choose ‘Edit’. 

  3. Add -Itest to the Default VM Arguments option.  Don’t forget the leading dash!


  4. Click ‘OK’. 


参考:Chris Cruft » Blog Archive » Aptana RadRails and the test_helper.rb LoadError


2008/08/18

Rails で、一つのフォームで複数のモデルを扱う

先日のRails講習で、いいことを学んだので忘れないうちにメモです・・。


Rails では、基本、一つの Form に一つの Model なのですが、 fields_for というヘルパーを使用することで複数のモデルを扱えます。


一対一のモデルを一度に更新する場合などに使えそうです。




  <% form_for @person, :url => { :action => "update" } do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>

<% fields_for @person.permission do |permission_fields| %>

Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<% end %>

参考:Rails Framework Documentation