Ruby on Rails 3.0 リリースノート

Rails 3.0は、晩ご飯も作れば洗濯物も畳んでくれる、夢のような製品です。Rails 3.0なしで今までどうやって暮らしていけたのか、不思議で仕方がなくなるでしょう。Rails 3.0は、これまでのRailsバージョンの中でかつてない高みに到達しました。

冗談はともかく、Rails 3.0は実によい仕上がりとなりました。Merbチームが我らがRailsチームに参加したことでもたらされた素晴らしいアイデアがすべて込められています。Merbチームはフレームワークの謎に満ちた内部をスリムかつ高速化し、素敵なAPIを多数もたらしてくれました。Merb 1.xをご存じの方であれば、Rails 3.0にその成果が多数盛り込まれていることがおわかりいただけるはずです。Rails 2.xをご存じの方もきっとRails 3.0を好きになっていただけるでしょう。

多くの機能や改良APIを搭載したRails 3.0は、内部がきれいになったかどうかに関心のない方も夢中になるでしょう。Railsアプリケーション開発者にとって、かつてないほど素晴らしい時期が到来しました。その中からいくつかご紹介します。

  • RESTful宣言を重視する新しいルーター
  • Action Controllerの後でモデル化される新しいAction Mailer API(もうマルチパートメッセージの送信で悩むことはありません!)
  • リレーショナル代数の上で構築される、Active Recordのチェーン可能なクエリ言語
  • Prototype.jsやjQueryなどのドライバを搭載したUnobtrusive JavaScript(UJS)ヘルパー(さようならインラインJS)
  • Bundlerによる明示的な依存性管理

そして何よりも、今回私たちは旧APIを非推奨化する際にできるかぎり適切なwarningを表示することを心がけました。つまり、Rails 3に移行するために、既存のアプリケーションの古いコードを今すぐ最新のベストプラクティスにすべて書き換えなくてもよいということです。

これらのリリースノートでは主要なアップグレードを取り扱いますが、細かなバグ修正や変更点については記載しませんのでご注意ください。Rails 3.0は、250人を超える人々による4,000件近いコミットを含みます。すべての変更点をチェックしたい方は、GitHub上のメインRailsリポジトリでコミットリストをご覧ください。

Rails 3のインストール方法は次のとおりです。

# セットアップで必要な場合はsudoを使います
$ gem install rails

1 Rails 3へのアップグレード

既存のアプリケーションをアップグレードするのであれば、その前に質のよいテストカバレッジを用意するのはよい考えです。アプリケーションがRails 2.3.5までアップグレードされていない場合は先にそれを完了し、アプリケーションが正常に動作することを十分確認してからRails 3にアップデートしてください。終わったら、以下の変更点にご注意ください。

1.1 Rails 3ではRuby 1.8.7以降が必須

Rails 3.0ではRuby 1.8.7以上が必須です。これより前のバージョンのRubyのサポートは公式に廃止されたため、速やかにRubyをアップグレードすべきです。Rails 3.0はRuby 1.9.2とも互換性があります。

Ruby 1.8.7のp248とp249には、Railsクラッシュの原因となるマーシャリングのバグがあります。なおRuby Enterprise Editionでは1.8.7-2010.02のリリースでこの問題が修正されました。現行のRuby 1.9のうち、Ruby 1.9.1はRails 3.0でセグメンテーションフォールト(segfault)で完全にダウンするため利用できません。Railsをスムーズに動かすため、Rails 3でRuby 1.9.xを使いたい場合は1.9.2をお使いください。

1.2 Railsの「アプリケーションオブジェクト」

Rails 3では、同一プロセス内で複数のRailsアプリケーション実行をサポートするための基礎の一環として、「アプリケーションオブジェクト」という概念が導入されました。1つのアプリケーションオブジェクトには、そのアプリケーション固有の設定がすべて保持されます。しかも、この設定は従来のRailsのconfig/environment.rbと極めて似通っています。

今後、各Railsアプリケーションはそれに対応するアプリケーションオブジェクトを持たなければなりません。このアプリケーションオブジェクトはconfig/application.rbで定義されます。既存のアプリケーションをRails 3にアップグレードする場合、このconfig/application.rbを追加して、config/environment.rb内の設定を適宜そこに移動しなければなりません。

1.3 script/*がscript/railsに置き換えられる

従来スクリプトの置き場に使われていたscriptディレクトリは、新しいscript/railsに置き換えられます。script/railsは直接実行するものではありませんが、Railsアプリケーションのルートディレクトリで呼び出されたことをrailsコマンドが検知して、代わりにスクリプトを実行します。望ましい用法は以下のとおりです。

$ rails console                      # script/consoleではない
$ rails g scaffold post title:string # script/generate scaffold post title:stringではない

rails --helpを実行すればすべてのオプションを表示できます。

1.4 依存関係とconfig.gem

従来のconfig.gemを用いる方式は廃止され、bundlerGemfileを用いる方式に置き換えられました。後述のgemに移行するを参照してください。

1.5 アップグレードプロセス

アップグレードプロセスを支援するために、Rails Upgradeというプラグインが自動化の一部として作成されました。

このプラグインをインストールしてrake rails:upgrade:checkを実行すれば、アプリ内でアップデートの必要な箇所をチェックできます(アップグレード方法の情報へのリンクも表示されます)。このプラグインは、config.gem呼び出しに基づいてGemfileを生成するタスクや、現在のルーティングから新しいルーティングファイルを生成するタスクも提供します。以下を実行すればプラグインを取得できます。

$ ruby script/plugin install git://github.com/rails/rails_upgrade.git

動作例については「Rails Upgradeプラグインが公式化された (英語)」で参照できます。

Rails Upgradeツール以外にも、支援が必要な場合はIRCやGoogleグループのrubyonrails-talkに自分と同じ問題に遭遇した人がおそらくいるでしょう。ぜひアップグレード作業をブログ記事にして、他の人々も知見を得られるようにしましょう。

2 Rails 3.0アプリケーションを作成する

# 'rails'というRubyGemがインストールされている必要があります。
$ rails new myapp
$ cd myapp

2.1 gemに移行する

今後のRailsでは、アプリケーションのルートディレクトリに置かれるGemfileを使って、アプリケーションの起動に必要なgemを指定するようになりました。このGemfileBundlerというgemによって処理され、依存関係のある必要なgemをすべてインストールします。依存するgemをそのアプリケーションの中にだけインストールして、OS環境にある既存のgemに影響を与えないようにすることもできます。

詳細情報: Bundlerホームページ

2.2 最新のgemを使う

BundlerGemfileのおかげで、専用のbundleコマンド一発でRailsアプリケーションのgemを簡単に安定させることができます。Gitリポジトリから直接bundleしたい場合は--edgeフラグを追加します。

$ rails new myapp --edge

Railsアプリケーションのリポジトリをローカルにチェックアウトしたものがあり、それを使ってアプリケーションを生成したい場合は、--devフラグを追加します。

$ ruby /path/to/rails/bin/rails new myapp --dev

3 Railsアーキテクチャの変更

Railsのアーキテクチャで6つの大きな変更点が発生しました。

3.1 Railtiesが一新された

Railtiesが更新され、Railsフレームワーク全体で一貫したプラグインAPIを提供するようになるとともに、ジェネレータやRailsバインディングが完全に書き直されました。これによって、開発者がジェネレータやアプリケーションフレームワークのあらゆる重要なステージに統一的かつ定義済みの方法でフックをかけられるようになりました。

3.2 Railsのあらゆるコアコンポーネントが分離された

MerbとRailsの主要なマージ作業の1つが、Railsのコアコンポーネントの密結合を切り離すことでした。この作業が完了したことで、Railsのあらゆるコアコンポーネントが同一のAPIを使うようになりました。これらのAPIはプラグイン開発に利用できます。つまり、作成したプラグインやコアコンポーネントを置き換える(DataMapperやSequelなど)際に、Railsコアコンポーネントからアクセスできるあらゆる機能にアクセスして自由自在に拡張できるようになったということです。

詳しくは「The Great Decoupling」を参照してください。

3.3 Active Modelを抽象化した

密結合したコアコンポーネントの切り離し作業の一環として、Active Recordへの結合をAction Packから切り出しました。この作業が完了したことで、新しいORMプラグインではActive Modelインターフェイスを実装するだけでAction Packとシームレスに協調動作できるようになりました。

詳しくは「Make Any Ruby Object Feel Like ActiveRecord」を参照してください。

3.4 コントローラを抽象化した

密結合したコアコンポーネントの切り離し作業として、基底スーパークラスを1つ作成しました。このクラスは、ビューのレンダリングなどを扱うHTTPの記法から分離されています。このAbstractControllerクラスを作成したことで、ActionControllerActionMailerが極めてシンプルになり、これらのライブラリすべてから共通部分が切り出されてAbstract Controllerに移動しました。

詳しくは「Rails Edge Architecture」を参照してください。

3.5 Arelを統合した

Arel(Active Relationとも呼ばれます)がActive Recordの下に配置され、Railsで必須のコンポーネントになりました。Arelは、Active Recordを簡潔にするSQL抽象化を提供し、Active Recordのリレーション機能を支えます。

詳しくは「Why I wrote Arel」を参照してください。

3.6 メールを切り出した

Action Mailerは最初期からモンキーパッチやプリパーサーだらけで、配信エージェントや受信エージェントまであり、さらにソースツリーでTMailをベンダリングしているというありさまでした。Rails 3では、メールに関連するあらゆる機能をMail gemで抽象化しました。こちらでもコードの重複が著しく解消され、Action Mailerとメールパーサーの間に定義可能な境界を作成しやすくなりました。

詳しくは「New Action Mailer API in Rails 3」を参照してください。

4 ドキュメント

Railsツリーのドキュメントが更新されてAPI変更がすべて反映されました。さらに、Rails EdgeガイドにもRails 3.0の変更点を順次反映中です。ただし、guides.rubyonrails.orgの本ガイドについては、安定版Railsのドキュメントのみを含みます(執筆時点では3.0がリリースされるまで2.3.5となります)。

詳しくは「Rails Documentation Projects」を参照してください。

5 国際化(I18n)

Rails 3では国際化(I18n)のサポートに関して、速度改善が著しい最新のI18n gemなど多くの作業が行われました。

  • あらゆるオブジェクトでのI18n: ActiveModel::TranslationActiveModel::Validationsを含むあらゆるオブジェクトにI18nの振る舞いを追加できます。訳文のerrors.messagesフォールバック機能もあります。
  • 属性にデフォルトの訳文を与えられます。
  • フォームのsubmitタグが、オブジェクトのステータスに応じて自動的に正しいステータス(CreateまたはUpdate)を取れるようになったことで、正しい訳文も取れるようになりました。
  • I18n化されたラベルに属性名を渡すだけで使えるようになりました。

詳しくは「Rails 3 I18n changes」を参照してください。

6 Railties

主要なRailsフレームワークの分離作業に伴って、Railtiesも大規模にオーバーホールされ、フレームワーク/エンジン/プラグインをできるだけ楽に拡張できる形で連結しました。

  • アプリケーションごとに独自の名前空間が与えられます。アプリケーションはたとえばアプリ名.bootで始まり、他のアプリケーションとのやりとりが今よりもずっと簡単になります。
  • Rails.root/app以下に置かれるものはすべて読み込みパスに追加されるようになりました。これにより、たとえばapp/observers/user_observer.rbを作るだけで、設定変更なしでRailsが読み込んでくれます。
  • Rails 3.0ではRails.configオブジェクトが提供されます。これは、Railsの膨大な設定オプションをすべて集約する中央リポジトリを提供します。

アプリケーション生成時に、test-unit/Active Record/Prototype.js/Gitのインストールをスキップするフラグも渡せるようになりました。また、--devフラグも新たに追加されたことで、Railsを指すGemfileをチェックアウト状態でアプリをセットアップできるようになりました(これはrailsバイナリへのパスで決定されます)。詳しくはrails --helpを参照してください。

Rails 3.0のRailtiesジェネレータでは、基本的に以下のようなさまざまな注意点があります。

  • ジェネレータが完全に書き直されたことで後方互換性が失われた
  • RailsテンプレートAPIとジェネレータAPIがマージされた: 利用上は従来と同じです
  • ジェネレータは特殊なパスからの読み込みを行わなくなった: 今後はRubyの読み込みパスのみを探索しますので、rails generate fooを呼び出すとgenerators/foo_generatorを探索します。
  • 新しいジェネレータではフックが提供される: あらゆるテンプレートエンジン/ORM/テストフレームワークを簡単にフックインできます
  • 新しいジェネレータでは、Rails.root/lib/templatesにテンプレートのコピーを置くことでテンプレートをオーバーライドできる
  • Rails::Generators::TestCaseも提供される: これを用いて独自のジェネレータを作成・テストできます

また、Railtiesジェネレータで生成されるビューについてもいくつかオーバーホールが行われました。

  • ビューでpタグの代わりにdivタグが使われるようになった
  • scaffoldジェネレータで、editビューとnewビューの重複コードの代わりに_formパーシャルを使うようになった
  • scaffoldフォームでf.submitが使われるようになった: これは、渡されるオブジェクトのステートに応じて「Create ModelName」または「Update ModelName」を返します

最後に、rakeタスクもいくつかの点が拡張されました。

  • rake db:forwardが追加された: マイグレーションを個別またはグループにまとめてロールフォワードできます
  • rake routes CONTROLLER=xが追加された: コントローラを1つ指定してルーティングを表示できます。

Railtiesで以下が非推奨化されました。

  • RAILS_ROOTが非推奨化: 今後はRails.rootを使います
  • RAILS_ENVが非推奨化: 今後はRails.envを使います
  • RAILS_DEFAULT_LOGGERが非推奨化: Rails.loggerを使います

PLUGIN/rails/tasksPLUGIN/tasksは今後どのタスクでも読み込まれなくなったので、今後はPLUGIN/lib/tasksを使わなければなりません。

詳しくは以下を参照してください。

7 Action Pack

Action Packは内部と外部ともに大きく変更されました。

7.1 Abstract Controller

Action Controllerから一般性の高い部分をAbstract Controllerに切り出して再利用可能なモジュールとし、テンプレートやパーシャルのレンダリング、ヘルパー、訳文、ログ出力など「リクエスト-レスポンス」サイクルのあらゆる要素をどのライブラリからでも利用できるようにしました。この抽象化によって、ActionMailer::BaseAbstractControllerを継承してRails DSLをMail gemでラップするだけで済むようになりました。

Abstract Controllerを導入したことで、Action Controllerのコードをクリーンアップするよい機会となり、コードをシンプルにする部分が抽象化されました。

ただし、Abstract Controllerはユーザー(開発者)が直接使うAPIではない点にご注意ください。日々のRails開発でAbstract Controllerを使うことはありません。

詳しくは「Rails Edge Architecture」を参照してください。

7.2 Action Controller

  • application_controller.rbprotect_from_forgeryがデフォルトで含まれるようになりました。
  • cookie_verifier_secretは非推奨化され、今後はRails.application.config.cookie_secretで代入されます。また、これはconfig/initializers/cookie_verification_secret.rbという独自のファイルに移動しました。
  • session_storeActionController::Base.sessionで設定されるようになり、Rails.application.config.session_storeに移動しました。デフォルトはconfig/initializers/session_store.rbで設定されます。
  • cookies.secureを用いて、暗号化された値をcookie.secure[:key] => valueでcookieに設定できます。
  • cookies.permanentを用いて、恒久的な値をcookie.permanent[:key] => valueでcookieハッシュに設定できます。署名済みの値が検証に失敗すると例外がraiseされます。
  • respond_toブロック内のformat呼び出しに、:notice => 'This is a flash message':alert => 'Something went wrong'を渡せるようになりました。flash[]ハッシュの動作は従来と同じです。
  • respond_withメソッドがコントローラに追加されます。これを用いて、込み入ったformatブロックをシンプルに書けます。
  • ActionController::Responderが追加されました。これを用いて、レスポンスを柔軟に生成できます。

以下が非推奨化されました。

  • filter_parameter_loggingが非推奨化されました。今後はconfig.filter_parameters << :passwordをお使いください。

詳しくは以下を参照してください。

7.3 Action Dispatch

Action DispatchはRails 3.0で新しく追加されました。これはルーティングの明快な実装を新たに提供します。

  • ルーターが大々的に書き直されてクリーンアップされたことで、RailsのルーターがRails DSLを持つrack_mountとなりました。これは単独のソフトウェアです。
  • 各アプリケーションで定義されるルーティングは、以下のようにApplicationモジュール内で名前空間化されるようになりました。

    # 従来
    
    ActionController::Routing::Routes.draw do |map|
      map.resources :posts
    end
    
    # 今後はこのように書く
    
    AppName::Application.routes do
      resources :posts
    end
    
  • matchメソッドがルーターに追加され、マッチしたルーティングに任意のRackアプリケーションも渡せるようになりました。

  • constraintsメソッドがルーターに追加され、定義済みの制約を用いてルーターを保護できるようになりました。

  • scopeメソッドがルーターに追加され、以下のようにさまざまな言語(ロケール)やアクションへのルーティングを名前空間化できるようになりました。

    scope 'es' do
      resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto'
    end
    
    # /es/proyecto/1/cambiarでeditアクションにアクセスできる
    
  • rootメソッドがルーターに追加され、これでmatch '/', :to => pathをショートカットできるようになりました。

  • マッチにセグメントをオプションとして渡せるようになりました。たとえばmatch "/:controller(/:action(/:id))(.:format)"の場合、丸かっこで囲まれた各セグメントがオプションになります。

  • ルーティングをブロックで表現できるようになりました。controller :home { match '/:action' }のように呼び出せます。

mapコマンドの旧来の書式は、後方互換性レイヤがあることで引き続き使えます。ただし、後方互換性レイヤは3.1リリースで削除される予定です。

以下が非推奨化されました。

  • 非RESTアプリケーションですべてのルーティングをキャッチする/:controller/:action/:idはコメントアウトされるようになりました。
  • :path_prefixルーティングは存在しなくなりました。また、:name_prefixに渡された値の末尾に自動的に"_"が追加されるようになりました。

詳しくは以下を参照してください。

7.4 Action View

7.4.1 Unobtrusive JavaScript(UJS)

Action Viewヘルパーで大規模な書き直しが行われ、Unobtrusive JavaScript(UJS)フックが実装され、旧来のインラインAJAXコマンドが削除されました。これによって、RailsでヘルパーでUJSフックを実装するときに任意のUJS準拠ドライバを利用できるようになりました。

具体的には、旧来のremote_<メソッド名>ヘルパーはRailsコアからすべて削除され、Prototype Legacy Helperに移動しました。今後UJSフックをHTML側で取得するには、以下のように:remote => trueを渡します。

form_for @post, :remote => true

上のコードから以下のHTMLが生成されます。

<form action="http://host.com" id="create-post" method="post" data-remote="true">
7.4.2 ヘルパーがブロックを受け取れるようになった

form_fordiv_forなどの、ブロック内のコンテンツを挿入するヘルパーが、以下のように<%=を使うようになりました。

<%= form_for @post do |f| %>
  ...
<% end %>

今後これと同様の自作ヘルパーは、手動で出力バッファにappendするのではなく、文字列を返すことが期待されます。

それ以外のヘルパー(cachecontent_forなど)は、この変更の影響を受けないため、従来同様&lt;%が必要です。

7.4.3 その他の変更
  • HTML出力をh(string)呼び出しでエスケープする必要はもうありません。h(string)はデフォルトであらゆるビューテンプレートで有効になります。エスケープを解除した(unescaped)文字列が欲しい場合はraw(string)を呼び出します。
  • ヘルパーがデフォルトでHTML5を出力するようになりました。
  • フォームラベルヘルパーが、単一の値を元にI18nの複数の値を取り出せるようになりました。つまり、f.label :nameとすると:nameの訳文を取り出します。
  • I18nのselectラベルは、今後:en.support.selectではなく:en.helpers.selectと記述すべきです。
  • ERBテンプレート内の式展開でHTML出力末尾のCR文字を除去するために置かれていたマイナス記号は、今後不要です。
  • Action Viewにgrouped_collection_selectヘルパーが追加されました。
  • content_for?が追加されました。これはレンダリング前のビューにコンテンツが存在するかどうかをチェックします。
  • :value => nilをフォームヘルパーに渡すと、デフォルト値を使わずにフィールドのvalue属性をnilに設定できます。
  • :id => nilをフォームヘルパーに渡すと、フィールドがid属性なしでレンダリングされます。
  • image_tag:alt => nilを渡すと、imgタグがalt属性なしでレンダリングされます。

8 Active Model

Rails 3.0で新たにActive Modelが導入されました。Active Modelは任意のORMライブラリを抽象化するレイヤを提供し、Active Modelインターフェイスを実装してRailsとやり取りするのに用います。

8.1 ORM抽象化とAction Packインターフェイス

コアコンポーネント分離作業の1つは、Active Recordへの結合をAction Packからすべて切り出すことでした。この作業が完了したことで、新しいORMプラグインはすべて、Active Modelインターフェイスを実装するだけでAction Packとシームレスにやりとりできるようになりました。

詳しくはMake Any Ruby Object Feel Like ActiveRecordを参照してください。

8.2 バリデーション

バリデーションがActive RecordからActive Modelに移動し、Rail 3のさまざまなORMライブラリで使えるバリデーションのインターフェイスを提供するようになりました。

  • validates :attribute, options_hashショートカットメソッドができました。これによって、あらゆるクラスメソッドのバリデーションに用いるオプションを渡せるようになり、1つのバリデーションメソッドに複数のオプションを渡せるようになりました。

  • validatesメソッドのオプションは以下のとおりです。

    • :acceptance => Boolean
    • :confirmation => Boolean
    • :exclusion => { :in => Enumerable }
    • :inclusion => { :in => Enumerable }
    • :format => { :with => Regexp, :on => :create }
    • :length => { :maximum => Fixnum }
    • :numericality => Boolean
    • :presence => Boolean
    • :uniqueness => Boolean

Rails 2.3スタイルのバリデーションメソッドはRails 3.0でも引き続きサポートされます。この新しいバリデーションメソッドの設計はモデルに新たなバリデーションを追加するためのものであり、既存APIを置き換えるものではありません。

バリデータオブジェクトを1つ渡すこともできます。バリデータオブジェクトは、Active Modelを利用するオブジェクト間で再利用できます。

class TitleValidator < ActiveModel::EachValidator
  Titles = ['Mr.', 'Mrs.', 'Dr.']
  def validate_each(record, attribute, value)
    unless Titles.include?(value)
      record.errors[attribute] << 'must be a valid title'
    end
  end
end
class Person
  include ActiveModel::Validations
  attr_accessor :title
  validates :title, :presence => true, :title => true
end

# Active Recordで用いる場合

class Person < ActiveRecord::Base
  validates :title, :presence => true, :title => true
end

以下のようなintrospectionもサポートします。

User.validators
User.validators_on(:login)

詳しくは以下を参照してください。

9 Active Record

Rails 3.0ではActive Recordについて集中的な作業が行われました。Active Modelへの抽象化、Arelによるクエリインターフェイスの全面的な更新、バリデーションの更新を含む多くの拡張や修正が行われました。Rail 2.x APIはすべて互換性レイヤを介して利用可能になっており、この互換性レイヤは3.1までサポートされます。

9.1 クエリインターフェイス

Active Recordのコアメソッド群が、Arelを用いて自身のリレーションを返すようになりました。Rails 2.3.xの既存のAPIは引き続きサポートされ、Rails 3.1までは非推奨化されず、Rails 3.2までは削除されません。ただし新しいAPIでは、以下の新しいメソッド群が提供され、どのメソッドも互いにチェーン可能なリレーションを返します。

  • where: 何を返すかという条件をリレーションに提供します。
  • select: モデルのどの属性をデータベースから返したいかを選択します。
  • group: 提供された属性のリレーションをグループ化します。
  • having: リレーションのグループ化を制約する式(GROUP BY制約)を提供します。
  • joins: リレーションを別のテーブルに結合(join)します。
  • clause: リレーションのjoinを制約する式(JOIN制約)を提供します。
  • includes: プリロードされた他のリレーションをインクルードします。
  • order: 提供された式に基づいてリレーションの並び順(order)を指定します。
  • limit: リレーションのレコード数を、指定の上限値に制限します(limit)。
  • lock: テーブルから返されたレコードをロックします。
  • readonly: データのコピーをリードオンリーにしたものを返します。
  • from: リレーションシップを複数のテーブルのどれから選択するかを指定します。
  • scope(旧named_scope): リレーションを返し、他のリレーションメソッドと互いにチェーンできるようにします。
  • with_scopewith_exclusive_scopeもリレーションを返すようになったことでチェーン可能になりました。
  • default_scopeもリレーションで使えるようになりました。

詳しくは以下を参照してください。

9.2 機能追加

  • :destroyed?がActive Recordオブジェクトに追加されました。
  • :inverse_ofActive Record関連付け(association)に追加され、読み込み済みの関連付けのインスタンスを、データベースにアクセスせずに取れるようになりました。

9.3 修正と非推奨化

Active Recordブランチでは他にも多数の修正が行われました。

  • SQLite2のサポートが終了し、SQLite3がサポート対象になった
  • MySQLのカラム順をサポート
  • PostgreSQLアダプタのTIME ZONEサポートが修正され、誤った値が挿入されないようになった
  • PostgreSQLテーブル名で複数のスキーマをサポート
  • PostgreSQLでXMLデータ型カラムをサポート
  • table_nameがキャッシュされるようになった
  • Oracleアダプタで多くの作業が行われ、バグも多数修正された

以下の非推奨化も行われました。

  • Active Recordクラスのnamed_scopeが非推奨化され、シンプルなscopeにリネームされた
  • scopeメソッドでは、従来の:conditions => {}ではなく今後リレーションメソッドを使うべき(例: scope :since, lambda {|time| where("created_at > ?", time) }
  • save(false)が非推奨化され、今後はsave(:validate => false)
  • Active RecordのI18nエラーメッセージは:en.activerecord.errors.templateから今後:en.errors.templateに変更すべき
  • model.errors.onが非推奨化され、今後はmodel.errors[]
  • validates_presence_of => validatesは今後:presence => true
  • ActiveRecord::Base.colorize_loggingconfig.active_record.colorize_loggingが非推奨化され、今後はそれぞれRails::LogSubscriber.colorize_loggingconfig.colorize_logging

数か月前にActive Recordのedge版にState Machineが実装されていましたが、Rails 3.0リリースからは削除されました。

10 Active Resource

Active ResourceもActive Modelに切り出されたことで、Action PackでActive Resourceオブジェクトをシームレスに利用できるようになりました。

  • Active Modelで使えるバリデーションを追加
  • observer用フックを追加
  • HTTPプロキシのサポート
  • ダイジェスト認証のサポートを追加
  • モデルの命名をActive Modelに移動
  • Active Resource属性をHashWithIndifferentAccessに変更
  • findスコープと同等なエイリアスfirstlastallを追加
  • find_everyで何も返されなかった場合にResourceNotFoundを返さないようになった
  • save!を追加(オブジェクトがvalid?でなければResourceInvalidをraiseする)
  • update_attributeupdate_attributesをActive Resourceモデルに追加
  • exists?を追加
  • SchemaDefinitionSchemaにリネーム、define_schemaschemaにリネーム
  • エラーの読み込みにリモートエラーのcontent-typeではなくActive Resourcesのformatを用いるようになった
  • スキーマブロックにはinstance_evalを用いるようになった
  • ActiveResource::ConnectionError#to_sを修正(@responseが#codeや#messageに応答しない場合にRuby 1.9互換になるようにする)
  • JSONフォーマットのエラーをサポート
  • loadが数値の配列でも使えるようになった
  • リモートリソースの410レスポンスを、リソースが削除されたと認識するようになった
  • Active Resource接続にSSLオプションを設定する機能を追加
  • コネクションのタイムアウト設定がNet::HTTPopen_timeoutにも効くようになった

以下は非推奨化されました。

  • save(false)が非推奨化され、今後はsave(:validate => false)
  • Ruby 1.9.2: URI.parse.decodeが非推奨化され、今後はライブラリで使われなくなった

11 Active Support

Active Supportの必要な機能だけを利用できるよう、多くの作業が行われました。これにより、Active Supportライブラリの一部の機能だけを使うために全体をrequireする必要がなくなりました。これにより、Railsのさまざまなコアコンポーネントがスリム化できるようになります。

Active Supportの主な変更点は以下のとおりです。

  • ライブラリをクリーンアップし、不要なメソッドを徹底的に削除しました。
  • Active SupportでTZInfoMemcache ClientBuilderのベンダリングバージョンの提供が終了しました。今後これらはすべて依存ライブラリに含まれ、bundle installコマンドでインストールされます。
  • ActiveSupport::SafeBufferに安全なバッファが実装された
  • Array.uniq_byArray.uniq_by!を追加
  • Array#randを削除し、Ruby 1.9からArray#sampleをバックポートした
  • TimeZone.seconds_to_utc_offsetが誤った値を返すバグを修正した
  • ActiveSupport::Notificationsミドルウェアを追加
  • ActiveSupport.use_standard_json_time_formatのデフォルトがtrueになった
  • ActiveSupport.escape_html_entities_in_jsonのデフォルトがfalseになった
  • Integer#multiple_of?がゼロを引数として受け取れるようになり、レシーバーがゼロでない場合にfalseを返すようになった
  • string.charsstring.mb_charsにリネームされた
  • ActiveSupport::OrderedHashがYAMLでデシリアライズできるようになった
  • XmlMini用のSaxベースのパーサーを追加(LibXMLとNokogiriを利用)
  • Object#presenceを追加(#present?の場合はオブジェクトを、それ以外の場合はnilを返す)
  • String#exclude?コア拡張を追加(#include?と逆の結果を返す)
  • DateTime属性を持つモデルでto_yamlが正しく動作するために、to_iActiveSupportDateTimeに追加
  • Enumerable#exclude?を追加(if !x.include?という書き方を避けるためEnumerable#include?と逆の結果を返す)
  • RailsのXSS(クロスサイトスクリプティング)のエスケープがデフォルトでオンになった
  • ActiveSupport::HashWithIndifferentAccessのdeepマージをサポート
  • Enumerable#sumがあらゆるenumerableで動作するようになった(:sizeに応答しない場合でも利用可能)
  • 長さゼロのdurationをinspectすると空文字列ではなく'0 seconds'が返るようになった
  • elementcollectionModelNameに追加
  • String#to_timeString#to_datetimeで分数形式の秒を扱うようになった
  • beforeコールバックやafterコールバックで:before:afterの両方に応答するaroundフィルタオブジェクトのコールバックを新たにサポートした
  • ActiveSupport::OrderedHash#to_aメソッドが返す配列セットがソート済みになった(Ruby 1.9のHash#to_aと一致)
  • MissingSourceFileは定数として存在するがLoadErrorと等価になった
  • Class#class_attributeを追加(値を継承可能でサブクラスから上書きできるクラスレベルの属性を宣言できる)
  • ActiveRecord::AssociationsDeprecatedCallbacksがついに削除された
  • Object#metaclassKernel#singleton_classになりRubyと一致するようになった

以下のメソッドはRuby 1.8.7と1.9で利用できるようになったため削除されました。

  • Integer#even?Integer#odd?
  • String#each_char
  • String#start_with?String#end_with?(三人称のエイリアスは保持)
  • String#bytesize
  • Object#tap
  • Symbol#to_proc
  • Object#instance_variable_defined?
  • Enumerable#none?

REXMLのセキュリティパッチは、初期パッチレベルのRuby 1.8.7で必要なため引き続きActive Supportに置かれています。適用が必要かどうかはActive Supportで認識されます。

以下のメソッドはフレームワークで今後使われないため削除されました。

  • Kernel#daemonize
  • Object#remove_subclasses_ofObject#extend_with_included_modules_fromObject#extended_by
  • Class#remove_class
  • Regexp#number_of_capturesRegexp.unoptionalizeRegexp.optionalizeRegexp#number_of_captures

12 Action Mailer

Action Mailerで、メールライブラリとしてTMailに代えて新たにMailに置き換えられた新しいAPIが提供されました。Action Mailer自身はほぼ完全に書き換えられ、多くのコードに手が入れられました。その結果Action MailerはAbstract Controllerをシンプルに継承するようになり、Rails DSLでMail gemをラップするようになりました。これにより、Action Mailer内の他のライブラリとのコード量や重複が著しく削減されました。

  • すべてのメーラーがデフォルトでapp/mailersに置かれるようになった
  • 新しいAPIを用いて3とおりの方法(attachmentsheadersmail)でメールを送信できるようになった
  • Action Mailerがattachments.inlineメソッドを用いてインライン添付ファイルをネイティブでサポートするようになった
  • Action Mailerのメール送信メソッドがMail::Messageオブジェクトを返すようになり、deliverメッセージを送信することで自分自身を送信できるようになった
  • 配信メソッドがすべてMail gemに抽象化された
  • mail配信メソッドが、有効なメールヘッダーのハッシュ(それらの値ペアを含む)を受け取れるようになった
  • mail配信メソッドがAction Controllerのrespond_toと似た振る舞いになり、テンプレートを明示的または暗黙的にレンダリングできるようになった(Action Mailerはメールを必要に応じてマルチパートメールにする)
  • mailのブロック内でformat.mime_type呼び出しにprocを1つ渡すことで、特定の種類のテキストを明示的にレンダリングしたり、レイアウトや別のテンプレートを追加したりできるようになった。そのproc内のrender呼び出しはAbstract Controllerのもので、同じオプションをサポートする。
  • メーラーの単体テスト項目が機能テストに移動した
  • Action Mailerがヘッダーフィールドや本文(body)の自動エンコーディングをMail gemに委譲した
  • Action Mailerがメールの本文やヘッダーを自動エンコードするようになった

以下は非推奨化されました。

  • :charset:content_type:mime_version:implicit_parts_orderはすべて非推奨化され、今後はActionMailer.default :key => value方式の宣言になった
  • メーラーの動的なcreate_method_namedeliver_method_nameが非推奨化された: 今後は単にmethod_nameを呼ぶこと(Mail::Messageオブジェクトが1つ返る)
  • ActionMailer.deliver(message)が非推奨化された: 今後は単にmessage.deliverを呼ぶこと
  • template_rootが非推奨化された: 今後はmail生成ブロック内のformat.mime_typeメソッドからのproc内でrender呼び出しにオプションを渡すこと
  • インスタンス変数を定義するbodyメソッド(body {:ivar => value})が非推奨化された: 今後はインスタンス変数をメソッド内で直接宣言するだけでビューで利用できるようになる
  • メーラーをapp/modelsに配置することが非推奨化された: 今後はapp/mailersを使うこと

詳しくは以下を参照してください。

13 クレジット表記

Rails3を頑丈かつ安定したフレームワークにするために多大な時間を費やしてくださった多くの開発者については、Railsコントリビューターの完全なリストを参照してください。これらの方々全員に敬意を表明いたします。

Rails 3.0リリースノート編集担当: Mikel Lindsaar

フィードバックについて

Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。

原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨

本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。

Railsガイド運営チーム (@RailsGuidesJP)

支援・協賛

Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。

  1. Star
  2. このエントリーをはてなブックマークに追加