おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

Rails 3にアップグレードしたら2.x系が作れなくなった

Rails 3.0 リリースノート和訳 - 前編に書かれていたやりかたでrailsを3にしてみました。

その状態で2.3.5のRailsアプリを作ろうとしたら下記のようにエラー

rails _2.3.5_ 2.3.5
/opt/ruby187/lib/ruby/site_ruby/1.8/rubygems.rb:827:in `report_activate_error': RubyGem version error: railties(3.0.0.beta not = 2.3.5) (Gem::LoadError)
        from /opt/ruby187/lib/ruby/site_ruby/1.8/rubygems.rb:261:in `activate'
        from /opt/ruby187/lib/ruby/site_ruby/1.8/rubygems.rb:68:in `gem'
        from /opt/ruby187/bin/rails:18

どうも、railsコマンドがrails 3 用に書き換えられてしまったようです。まだrails2.x系も使いたいので困りましたが、railsコマンドを下記のように書き換えたら動きました。

#!/opt/ruby187/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
  version = $1
  ARGV.shift
end

if version < "3"
  gem 'rails', version
  load 'rails'
else
  gem 'railties', version
  load Gem.bin_path('railties', 'rails', version)
end

Rails 3.0 リリースノート和訳 - 前編

Rails 3.0: Release Notes

の和訳をしています。量が膨大なのでとりあえず半分をエントリとして切り出しました。基本的に意訳で適当に削除したり付け加えたりしてる部分もあります。もし間違い等見つけたらご連絡をお願いします><

後編は一週間後くらいまでに書きます。

(追記)
id:gom68さんが全文の和訳をされているので、全文の和訳が見たい方はこちらを参照してください。
Rails3 リリースノート全文和訳 (ただし適当) - うっかりプログラミング日誌

↑があるので後編は急がず、それぞれの章の深掘りを先にやるかもしれませんー

(追記)
後編書きました

Rails 3.0 リリースノート和訳 - 後編 - おもしろWEBサービス開発日記

まえがき

Rails3.0はまだベータ版。バグがあるかもしれないので見つけたらこちらに報告してね。空軍の核爆弾発射アプリのような正確さが求められるアプリをRails 3.0でつくっちゃだめですよ。でももしこれから新しいアプリを開発するのなら恐れずに使ってみてね。

Rails 3 プレリリースベータ版をインストールするためには、下記のようにまずRailsが依存しているgemをrubygemsでインストールする必要があるよ

# Use sudo if your setup requires it
gem install tzinfo builder i18n memcache-client rack \
  rake rack-test rack-mount erubis mail text-format \
  thor bundler
gem install rails --pre

1 Rails3へのアップグレード

アップグレードするなら、その前にきちんとテストコードを書いといた方がいいよ。まず2.3.5にアップグレードして、きちんと動くことを確認してから3にアップグレードした方がいいよ。

1.1 Rails3はRuby1.8.7以上が必要

Rails3はRuby1.8.7以上が必要。公式的には1.8.7より前のRubyはサポートしません。Rails3.0は1.9.2と互換性あるよ。

1.2 Rails Application object

同じプロセス上で複数Railsアプリを動かすための土台として、Rails3ではApplication objectという概念を導入したよ。Application objectは一つで全てのアプリの設定を保持するconfig/environment.rbのようなものだよ。

それぞれのRailsアプリは対応するapplication objectを持ってないといけないよ。application objectはconfig/application.rbで定義されてる。もし既存のアプリをRails3にアップグレードするなら、config/application.rbを追加して適切な設定をconfig/environment.rbから移動させる必要があるよ。

1.3 script/* は script/railsに移行した

scriptディレクトリに置かれていたスクリプトは全部script/railsに移行したよ。スクリプトコマンドを実行したいときは、script/railsを直接実行せずにrailsコマンドを実行しましょう。railsコマンドはrailsのルートディレクトリで呼び出されたかを検知してスクリプトを実行してくれるよ。

実行例

rails console # => ./script/console 
rails g scaffold post title:string # => ./script/generate scaffold post title:string

1.4 config.gem

config.gemメソッドはbundlerとGemfileに置き換わったよ。詳しくは2.1を参照のこと。

1.5 Upgrade Process

アップグレードの一部を自動化してくれるプラグインrails upgradeがあるよ。

プラグインをインストールして、

rake rails:upgrade:check

とするとアプリをチェックして、アップデートするのに必要な情報を表示してくれるし、さらにアプリのconfig.gemをみてGemfileを作ってくれるよ。さらにroutesファイルも同じように今のアプリのを参考にして作ってくれるよ。

rails upgradeプラグインのインストールは下記のようにするとできるよ。

rails plugin install git://github.com/rails/rails_upgrade.git 

実行例はomgbloglol - rails-upgrade is now an official pluginを参考にしてね。

Railsのアップグレードに関してもっといろいろ助けが欲しければIRCに詳しい人がいるしRuby on Rails: Talk | Google グループとかをあたると同じような問題がヒットするかも。問題が解決したらその経験をブログに書いてみんなで知識をシェアしようね!

さらに詳しい情報はこちら - The Path to Rails 3: Approaching the upgrade

2 Rails3.0アプリの作り方

railsのベータ版のインストール方法

gem install rails --prerelease
rails myapp
cd myapp

2.1 Vendoring Gems

アプリを実行するのに必要なgemはRAILS_ROOT/Gemfileに記述するよ。GemfileはBundlerと呼ばれるプラグインで処理されるよ。Bundlerは依存関係にあるgemをインストールするプラグインで、依存関係にあるgemを全てローカルにダウンロードして、アプリがシステムのgemに依存しないようにすることもできるよ。

詳しくはこちら

bundler README on Github

2.2 EdgeなRailsを使うには

BundlerとGemfileのおかげで、コマンド一発でrailsアプリを簡単に凍結できるようになったよ。rake freezeはもう使わないよ。

gitリポジトリから直接edge railsを持ってきてfreezeしたい時には --edge フラグをつける

rails myapp --edge

ローカルにRailsリポジトリをチェックアウトしたものがあってそこからrailsアプリを生成したい場合は --dev フラグをつける

ruby /path/to/rails/railties/bin/rails myapp --dev 

3 Railsアーキテクチャ的な変更

Railsアーキテクチャに関する6つの大きな変更について

3.1 Railtiesの書き直し

generatorとRails bindingsを書き直したのと同じように、Railties(Railsのコアライブラリ)も書き直したよ。

3.2 全てのRailsコアなコンポーネント疎結合にした

MerbとRailsを統合するにあたっての大仕事として、Railsのコアなコンポーネントの密結合を疎結合にするのがあったよ。これを達成したことによって、全てのRailsコアコンポーネントは、みんなが普通にアクセスできるAPIと同じAPIを使うようになったよ。これによってどんな自作プラグインでも、どんな置き換えコアコンポーネント(例えばDataMapperやSequel)でも、Railsのコアコンポーネントがアクセスできる全ての機能にアクセスしたり拡張したりできるようになったよ。

詳しくはこちら

The Great Decoupling

3.3 Active Modelによる抽象化

コアコンポーネント疎結合化のひとつとして、Action PackからActive Recordを切り離したよ。全ての新しいORMプラグインはAction Packと一緒に使うためにActive Modelをimplementする必要があるよ。

詳しくはこちら

Make Any Ruby Object Feel Like ActiveRecord

3.4 コントローラの抽象化

コアコンポーネント疎結合化のひとつとして、HTTPの概念とは切り離してビューのレンダリングを管理することを目的としたスーパークラスAbstractControllerを作ったよ。ActionControllerとActionMailerに共通するコードをAbstractControllerに移動してコードをスリムにしたよ。

詳しくはこちら

Rails Edge Architecture

3.5 Arelとの統合

Arel(またの名を Active Relation)はActive Recordの下層に位置するコンポーネントでRails3.0で使われているよ。ArelがSQLの抽象化や関連系の機能をサポートしてくれるのでActive Recordの構造を単純にできるよ。

詳しくはこちら

Why I wrote Arel.

3.6 Mail Extraction

TMailのソースコードに、パーサと送信受信エージェントを追加するモンキーパッチをあてたのがAction Mailerの始まりだったよ。Rails3ではメール文章関連の機能は抽象化してMail gemに移すよ。これでコードの重複が減ってAction Mailerとemail parserの間の境界を定義しやすくするよ。

詳しくはこちら

New Action Mailer API in Rails 3

4 Documentation

Railsのドキュメントは全てのAPIの変更に追随してアップデートしているところだよ。さらに、Rails Edge guidesも少しずつRails 3.0の変更を反映していっているよ。でもRuby on Rails guidesはstableなバージョンのRailsだけを載せ続けるよ(3.0がリリースされるまでは2.3.5)

詳しくはこちら

Rails Documentation Projects

5 国際化

Rails3での国際化のサポートのためにたくさん労力をかけたよ。最新のi18n gemはすごい早さで進化していってるよ。

  • I18nは ActiveModel::Translation と ActiveModel::Validations をincludeすればどんなオブジェクトにも使えるよ。これまでORM毎にtranslationを定義してたけどerrors.messages で全体のエラーメッセージを扱えるようになったよ。
  • 2.3まではModelのattributes単位で翻訳した文字列を定義してたけど、これからはattributes単位で(Modelを横断して)デフォルトの翻訳した文字列を指定できるよ
  • フォームのsubmitメソッドは自動的にformにセットされたオブジェクトの状態を見て(新規作成なのか変更なのか)、それに対応した文字列を出力するよ。
  • ラベルはattributeの名前を指定するだけで翻訳して出力するよ

詳しくはこちら

Rails 3 I18n changes

6 Railties

疎結合化の過程で、Railtiesは他のフレームワークやエンジンやプラグインと連携するために総点検を受けたよ。なるべく痛みを伴わずにかつなるべく拡張できるように。

  • それぞれのアプリケーションは自分の名前空間を持つようになった。例えばアプリケーションは "アプリケーションの名前".bootで実行される。それによって他のアプリケーションともっと簡単に連携できるようになったよ。
  • Rails.root/appの配下のディレクトリは全てload pathに加えられるよ。なのでapp/observers/user_observer.rbなどを作っても特にload pathをいじらずにRailsはそれをloadするよ。
  • Rails 3.0は全てのconfig的な定義の中心としてRails.configオブジェクトを使うよ。

railsコマンドによるrailsアプリの生成時にオプションでtest-unitやActive Record、PrototypeやGitなどのインストールを飛ばすことが出来るよ。-devオプションはRailsリポジトリからチェックアウトしたものを指定してGemfileにその情報を書き込んでrailsアプリを生成するよ。

詳しい情報はrails -helpでみてね。

Rails3.0でのRailtiesのgeneratorsはめちゃめちゃ注目されてるよ。基本的にはこんな感じ

  • Generatorsは完全に書き直されて過去のものと互換性がないよ。
  • Railsのtemplates APIとgenerators APIがマージされたよ
  • Generatorsはもうこれ以上特別なpathからloadされることはないよ。Ruby load pathでしかみつかんないよ。例えばgenerators/foo_generatorを呼び出すためにはrails generate fooとするよ。
  • 新しいgeneratorsはフックを提供するよ。template engine、ORM、テストフレームワークなんかが簡単にgeneratorsにフックできるよ。
  • 新しいgeneratorsはRAILS_ROOT/lib/templatesにテンプレートのコピーを配置することでテンプレートを上書きできるよ。
  • Rails::Generators::TestCaseで自分のgeneratorsを作ってテスト出来るよ

generatorによって作られたviewについての変更点

  • これまでpタグを使っていたところにdivタグを使うようになったよ
  • Scaffoldsはeditとnewのviewに、コードの重複を避けるために部分テンプレートとして_formを使ってるよ。
  • Scaffold出作られたformでf.submitを使っていて、これはオブジェクトの状態を見て"Create ModelName"または"Update ModelName"のvalueになるよ(i18nの章でも同じようなこと書いてたね)。

rakeタスクにも二つの追加があるよ

  • rake db:forward が追加されたよ。これでmigrationを一つだけ進めたり指定した分だけ進めたりができるよ。
  • rake routes CONTROLLER=x が追加されたよ。指定されたコントローラのルーティングだけを表示するよ。

Railtiesは下記の三つの定数を変更して、古い方を非推奨にするよ

PLUGIN/rails/tasksとPLUGIN/tasksはもうどのタスクでもロードされないよ。全てのタスクはPLUGIN/lib/tasksにあるよ。

詳しくはこちら

Discovering Rails 3 generators
Making Generators for Rails 3 with Thor