2010-12-11

今さら始めるRails 3

Ruby との付き合いはそれなりに長いのですが実は Rails で何かを作ったことは一度もありません。1scaffold や migration は一通り試してみたことがあったけれども、何か拭えない不安感や縁のなさから今までは周辺技術の一つとして以上には触ったことがありませんでした。

興味

今回、出遅れはしたけれども

  • 全面的に Merb & Rack ベース
  • Arel 登場
  • i18n の機構が組み込み済み
  • すでに実績が増えてきている

辺りで強く興味が湧いてきたのでまずは一通りの準備をしてみました。

消極的な理由

消極的な理由も実はあって、それは

  • PHP のレガシーコードと戦うのに疲れた
  • 負債のある PHP で最新バージョンに追いつくのは大変
  • 最新バージョンでないと PHP や PHP のフレームワークの旨味は味わえない
  • Ruby なら最新でなくたって遊べる
  • Rails の過去の作法をほとんど知らないので混乱しない

他のどんな言語でも似たようなものだとは思いますが、レガシーコードを大量に抱えてしまうとアップグレードできずにキャッチアップが難しくなります。また rvm のような仕組みもない PHP では最新の情報を手元でだけ試しておくという準備もしにくいです。その点 Ruby には rvm もあるし gem は複数バージョンを保持できるし、良いテストの文化があります。

まずはインストール

の、前に Ruby は 1.8.7 以上が必要です。Windows なら installer で入れればいいです。rvm をすでに使っているなら好きなものを入れてください。困るのは RHEL 5 系 Linux でバイナリインストールしかしない人で、その場合は

End Point Package Repository

を使ってください。RHEL 6 な人は Rails 3 ready らしいです。

あとやることは

$ gem install rails

だけ。依存ライブラリはどかどか入りますので、しばらく待ちます。あとは必要に応じて

  • sqlite3-ruby
  • rails-erd
  • jpmobile
  • rspec-rails
  • typus
  • jasmine
  • cucumber-rails

など、お好みで。Cucumber はまだズルズルきております。いい加減やらないと。

RSpec は 2 以上が Rails 3 対応です。現時点(2010-12-11)では何も考えずに最新を入れれば大丈夫です。本当に Rails 3 のリリースにみんなが足並みを揃えたことがよく分かります。ありがとう。

アプリケーションの雛形準備

rails new foo でアプリの雛形を作成します。

$ rails new foo -T -J

このとき -T -J でそれぞれ Test::Unit と prototype.js 依存を取り除けます。が、ここではまだ取り除けるだけ。

Gemfile の編集

Rails 3 からは Bundler の仕組みを使って依存 gem を管理します。どういうことかというと

  1. 使いたい gem を Gemfile に列挙
  2. Gemfile を編集したら bundle install

が、おまじないとして増えたということです。

これはもしかしたら面倒に感じる人が多いかもしれませんが、サーバ管理する人間からすると、どのアプリで何のライブラリを使ってるのかよく分からない状況になりがちで「もう全部 rsync すればいんじゃね」くらいしか打つ手のなかった最近の状況に対するとてもスマートな回答として、個人的には嬉しく思っています。大規模なサイトしか相手にしない場合はライブラリ管理は「そのサイトで必要なもの全部」なのでそこまで面倒じゃないのですが、小さいものをいくつも VirtualHost で収めているような場合は困ります。

ここでは以下のようにしてとりあえずどかどかインストールしてみます。

gem 'jpmobile'
# gem 'jquery_rails3' # NOT WORK !!
gem 'jquery-rails'

group :development, :test do
  gem 'rails-erd'
  gem 'rspec-rails'
  gem 'jasmine'
  gem 'typus'
end

こんな感じ。

では以下に各 gem の使い方などを簡単に紹介していきます。

rails-erd

Rails ERD – Entity-Relationship Diagrams for Rails

これは面白いです。Rails 3 用というか正確には ActiveRecord 3 用で、

生成済みの Model の情報から ER 図をそれっぽく起こします。

graphviz に依存していますし、graphviz のバージョンによってはきれいな図が描けないので注意が必要です。すべて適切に動いていれば

rake erd

で ERD.pdf が作成されます。これで Rails の環境から離れてマウスをポチポチやることなく ER 図が作れます。嬉しい。それに最近の ORM を使った開発では DBMS を抽象化しているので DBMS を schema dump しても正しい関係を抽出できないんですよね。リレーションも DBMS ではなく Model 間で考える必要がある2ので、こういうツールがとても嬉しいです。

※ 試した範囲では以下のような感じで動いたり動かなかったりしました。

バージョンプラットフォーム結果
2.26MacPortsOK
2.22CentOS 5NG
(失念)FinkNG
2.20DebianOK

単に新しい方がよい、ってわけでもないみたいです。

RSpec

RSpec - Relish

bundle install に成功していれば rails g コマンドに rspec:install が現れる3ので、これを使って spec の雛形を用意します。

$ rails g rspec:install

まだ実際に spec を書いたことはないので、以下略。

jQuery

[2010-12-27 修正]

indirect/jquery-rails - GitHub

Rails 標準は prototype.js なのですが、これは先ほどの rails new で抑止してあるので、改めて jQuery を入れます。rspec と同様に rails g コマンドに jquery:install ができます。

$ rails g jquery:install

最初間違ってしまったのですが、jquery_rails3 はダメで、jquery-rails だとうまくインストールできます。

もしすでに prototype.js 依存で project を new してしまっていてもちゃんと取り除いてくれます。

なんかエラー出ますね。git の最新 jquery を取得する処理でコケてるっぽいです。https 周りかな。

放置します。

今回はとりあえずカッコがつけばいいので。

jpmobile

jpmobile - A Rails plugin for Japanese mobile-phones

すんなり使えます。ただし実際に機能させるには config をいじらないとダメです。Rails の config はこの辺にあります。

RAILS_ROOT/config/
├── application.rb
...
├── environment.rb
...

今回は environment.rb を以下のようにいじってみました。どこをいじるのが正解なのかは分かりませんが。

# Load the rails application
require File.expand_path('../application', __FILE__)

module Demo
  class Application
    # jpmobile
    config.jpmobile.mobile_filter
  end
end

# Initialize the rails application
Demo::Application.initialize!

これだけで端末に応じた view の振り分けはすぐに使えます。キャリアに応じて文字コードの変換も自動でやってくれるし、スマートフォン対応も簡単にできそうです。これは便利。

※ 今回 Rails 3 に関心を持っているもう一つの理由がこの jpmobile です。PHP でモバイル対応しようとしてもこれだけの完成度のものは公開されていないと思います。

Bundler

Bundler: The best way to manage Ruby applications

bundle install はすでに使っていますが、

$ bundle install [PATH]

あるいは

$ bundle install --deployment

を実行すると RAILS_ROOT/.bundle/config が作成され、この中にパスの情報が残るようです。この情報が残っている限りは単に

$ bundle install

を実行しても system の gem のパスではなく、プロジェクト独自のパスに入るようになります。なるほどなぁ。

Typusで管理画面は横着する

Typus Core: Admin Panel for Ruby on Rails Applications

DBMS を使うアプリで面倒なのはやはり管理画面じゃないですかね。管理画面がないとずっとお守りをしなければいけなくなるけど、表に見えるわけじゃないのでつい億劫になりがちです。

そこで管理画面の作成を助けてくれるものは必要だろうと以前から思っていたのですが、とりあえず Typus は現状でも Rails 3 で使えそうです。

$ rails g model

….

$ rake db:migrate
$ rails g typus

すると、作成済みのモデルの情報からそれなりの管理画面が自動で生成されます。

ただし、model の変更には恐らく追随できないので、ある程度構造が固まってから generate した方がいいかもしれません。

ruby-toolbox.com の Rails Admin Interfaces で2番人気、Rails 3 対応のものでは1番人気なので、外れではないんじゃないでしょうか。

※ 実は Typus を試す前に Casein - A lightweight Ruby on Rails CMS を試していたのですが、jpmobile とぶつかってにっちもさっちもいかなくなっていたのでやめました。見た目的には Casein の方がかっこよさそうなんですけどね。

Jasmine

Jasmine: BDD for Javascript | Jasmine

これは以前の紹介と違って

$ bundle exec jasmine init

するだけです。あとは一緒。

Arel

$ rails console

の中でちょっと試してみました。

Model.select( 'foo, bar' ).where( 'bar != baz' ).limit( 2 )

みたいに書いていきなり結果が取得できます。うっは。おまけに

.to_sql

を付ければ発行される SQL がすぐに確認できます。

なんじゃこりゃ!

ORM への抵抗が一気になくなりますよ、これ。ステキすぎます。

i18n

※ できることとできないことが分かりました。

RAILS_ROOT/config/locales/

以下に .rb な Hash か .yml な YAML でメッセージカタログを用意するのが標準の方法みたいです。

ここでいじったものはちゃんと locale の設定ができていれば Typus で自動生成した管理画面にも反映されます。ちょっと感動。4

ただし Typus が model 名ではなくテーブル名を表示してしまう5ので、model 名に日本語を割り当てても「モデル名s」っていう謎の表記になってしまいます。

これは…バグと言った方がいいのかなぁ?

[2010-12-26 追記] 分かりました。

Typus は generate した際に

/app/views/admin/

以下にいろいろ HTML を吐くのですが、その中で

@resource.model_name.human.pluralize

<%= _t(key.constantize.model_name.human.pluralize) %>

こんな記述が出てきます。この pluralize がダメです。

active support の inflection である pluralize は Rails の i18n の守備範囲外なので、model_name.human のあとに呼んじゃダメなのでした。また、Rails の i18n は

5.1 Translations for Active Record Models - Ruby on Rails Guides: Rails Internationalization (I18n) API

にあるように model の名前に対して翻訳を割り当てます。table_name に割り当てる機能があれば .pluralize があっても正しく機能させることも無理ではなさそうですが、現状(3.0.3)ではできません。

model.human のあとに pluralize は呼んじゃダメ

と覚えることにします。

なお、twitter 上で .model_name.human じゃなくて .human_name にすればよかったと書きましたが、human_name は deprecated でした。

残りの課題

ざっと作業だけ見てきましたが、今後の課題は

  • fixture
  • rspec
  • cucumber
  • 「モデルのリレーションシップ」という概念の習得

でしょうか。ORM の利用経験もあまりないため、foreign key を明示せずに Model 中心に考えることがどうもまだしっくりきていません。schema dump してみても

なんだこのスカスカした感じは

というのが率直な感想です。しばらくは戸惑いも残るでしょうが、早く「モデルのリレーションシップ」という考え方に頭を慣れさせないとダメですね。

  1. もともと公開できるプロダクトなんかほとんどないんだけど。 

  2. っぽいことを今痛感している最中なのでもしかしたら変なこと言ってるかも 

  3. rails g –help とすると確認できる 

  4. locale の変更に関しては development 環境でも再起動が必要みたいですね。カタログの変更はすぐに反映されますが。まぁ locale の変更なんて何度もしないので問題ないですけど、知らないと locale が反映されていないのか自分のカタログファイルの用意の仕方がおかしいのか分からないのでちょっと注意が必要です。 

  5. 正確には model_name をわざわざ pluralize したもの 

About

例によって個人のなんちゃらです