edge
詳細はrubyonrails.orgで: もっとRuby on Rails

Ruby on Rails 2.2 リリースノート

Rails 2.2 には、いくつかの新機能と改善が含まれています。このリストでは主要なアップグレードをカバーしていますが、すべてのバグ修正や変更は含まれていません。すべてを確認したい場合は、GitHub のメイン Rails リポジトリの コミットリスト をご覧ください。

Rails とともに、2.2 は Ruby on Rails Guides の開始をマークしています。これは進行中の Rails Guides hackfest の最初の成果物であり、Rails の主要な機能の高品質なドキュメントを提供します。

1 インフラストラクチャ

Rails 2.2 は、Rails をスムーズに動作させ、他のシステムと接続するためのインフラストラクチャにとって重要なリリースです。

1.1 国際化

Rails 2.2 は、国際化(または i18n)のための簡単なシステムを提供します。

1.2 Ruby 1.9 および JRuby との互換性

スレッドセーフティに加えて、Rails は JRuby および今後の Ruby 1.9 との互換性を確保するために多くの作業が行われました。Ruby 1.9 は移動するターゲットであるため、エッジ Rails をエッジ Ruby で実行することはまだ確実ではありませんが、Rails は後者がリリースされた時点で Ruby 1.9 への移行に備えています。

2 ドキュメント

Rails の内部ドキュメントは、コードコメントの形式で多くの場所で改善されています。さらに、Ruby on Rails Guides プロジェクトは、主要な Rails コンポーネントの情報の決定版です。最初の公式リリースでは、Guides ページには以下が含まれています。

全体で、Guides は初心者から中級者の Rails 開発者に対して数万語のガイダンスを提供しています。

これらのガイドをローカルで生成するには、アプリケーション内で次のコマンドを実行します。

$ rake doc:guides

これにより、ガイドが Rails.root/doc/guides 内に配置され、お気に入りのブラウザで Rails.root/doc/guides/index.html を開くことで直接閲覧できます。

3 HTTP とのより良い統合: ボックス外の ETag サポート

HTTP ヘッダーでの ETag と最終変更日時のサポートにより、Rails は最近変更されていないリソースのリクエストを受け取った場合に空のレスポンスを返すことができるようになりました。これにより、レスポンスを送信する必要があるかどうかを確認できます。

class ArticlesController < ApplicationController
  def show_with_respond_to_block
    @article = Article.find(params[:id])

    # リクエストが stale? へのオプションと異なるヘッダーを送信した場合、リクエストは実際には古くなっており、
    # respond_to ブロックがトリガーされます(および stale? 呼び出しのオプションがレスポンスに設定されます)。
    #
    # リクエストヘッダーが一致する場合、リクエストは新鮮であり、respond_to ブロックはトリガーされません。
    # 代わりに、デフォルトのレンダリングが行われます。これにより、last-modified および etag ヘッダーがチェックされ、
    # テンプレートのレンダリングではなく "304 Not Modified" を送信する必要があることが判断されます。
    if stale?(:last_modified => @article.published_at.utc, :etag => @article)
      respond_to do |wants|
        # 通常のレスポンス処理
      end
    end
  end

  def show_with_implied_render
    @article = Article.find(params[:id])

    # レスポンスヘッダーを設定し、リクエストと照合します。リクエストが新鮮でない場合
    # (つまり、etag または last-modified のいずれも一致しない場合)、
    # テンプレートのデフォルトのレンダリングが行われます。
    # リクエストが新鮮な場合、デフォルトのレンダリングは "304 Not Modified" を返し、
    # テンプレートのレンダリングは行われません。
    fresh_when(:last_modified => @article.published_at.utc, :etag => @article)
  end
end

4 スレッドセーフティ

Rails のスレッドセーフ化に関する作業は、Rails 2.2 で展開されています。ウェブサーバーインフラストラクチャに応じて、これによりメモリ内の Rails のコピーを減らすことで、より多くのリクエストを処理し、サーバーのパフォーマンスを向上させ、複数のコアの利用率を高めることができます。 アプリケーションの本番モードでマルチスレッドディスパッチを有効にするには、config/environments/production.rbに以下の行を追加してください。

config.threadsafe!

5 Active Record

ここでは、トランザクションマイグレーションとプールされたデータベーストランザクションの2つの大きな追加点について説明します。また、結合テーブル条件の新しい(そしてよりクリーンな)構文や、その他の改善点もあります。

5.1 トランザクションマイグレーション

従来、複数のステップを必要とするRailsのマイグレーションは問題の元でした。マイグレーション中に何か問題が発生した場合、エラーが発生するまでのすべての変更がデータベースに反映され、エラーが発生した後の変更は適用されませんでした。また、マイグレーションのバージョンは実行済みとして保存されていたため、問題を修正した後に単純にrake db:migrate:redoで再実行することはできませんでした。トランザクションマイグレーションは、これを改善するために、マイグレーションステップをDDLトランザクションでラップし、いずれかのステップが失敗した場合はマイグレーション全体を元に戻す仕組みです。Rails 2.2では、トランザクションマイグレーションはPostgreSQLでサポートされています。コードは将来的に他のデータベースタイプにも拡張可能であり、IBMは既にDB2アダプタをサポートするために拡張しています。

5.2 コネクションプーリング

コネクションプーリングを使用すると、Railsはデータベースリクエストをデータベース接続のプールに分散させることができます。デフォルトでは最大サイズ(デフォルトでは5ですが、database.ymlpoolキーを追加して調整することもできます)まで成長します。これにより、多くの同時ユーザをサポートするアプリケーションのボトルネックが解消されます。また、ギブアップする前の待機タイムアウトはデフォルトで5秒です。ActiveRecord::Base.connection_poolを使用すると、必要に応じてプールに直接アクセスできます。

development:
  adapter: mysql
  username: root
  database: sample_development
  pool: 10
  wait_timeout: 10

5.3 結合テーブル条件のハッシュ

ハッシュを使用して結合テーブルの条件を指定することができます。これは、複雑な結合をクエリする必要がある場合に大いに役立ちます。

class Photo < ActiveRecord::Base
  belongs_to :product
end

class Product < ActiveRecord::Base
  has_many :photos
end

# 著作権フリーの写真を持つすべての商品を取得する
Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})

5.4 新しいダイナミックファインダー

Active Recordのダイナミックファインダーファミリーには、2つの新しいメソッドセットが追加されました。

5.4.1 find_last_by_attribute

find_last_by_attributeメソッドは、Model.last(:conditions => {:attribute => value})と同等です。

# ロンドンから最後にサインアップしたユーザーを取得する
User.find_last_by_city('London')

5.4.2 find_by_attribute!

find_by_attribute!の新しいbang!バージョンは、Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFoundと同等です。一致するレコードが見つからない場合、このメソッドはnilを返す代わりに例外を発生させます。

# 'Moby'がまだサインアップしていない場合は、ActiveRecord::RecordNotFound例外を発生させる!
User.find_by_name!('Moby')

5.5 関連はprivate/protectedスコープを尊重する

Active Recordの関連プロキシは、プロキシされたオブジェクトのメソッドのスコープを尊重するようになりました。以前は(Userがhas_one :accountを持つ場合)、@user.account.private_methodは関連するAccountオブジェクトのprivateメソッドを呼び出していました。これはRails 2.2では失敗します。この機能が必要な場合は、@user.account.send(:private_method)を使用するか、メソッドをprivateまたはprotectedではなくpublicにする必要があります。なお、method_missingをオーバーライドしている場合は、関連が正常に機能するためにrespond_toもオーバーライドする必要があります。

5.6 その他のActive Recordの変更点

  • rake db:migrate:redoは、再実行する特定のマイグレーションを対象とするためのオプションのVERSIONを受け入れるようになりました。
  • config.active_record.timestamped_migrations = falseを設定すると、UTCタイムスタンプの代わりに数値プレフィックスを持つマイグレーションが作成されます。
  • :counter_cache => trueで宣言された関連のカウンターキャッシュカラムは、もはやゼロで初期化する必要はありません。
  • ActiveRecord::Base.human_nameは、モデル名の国際化対応のヒューマンな翻訳を提供します。

6 Action Controller

コントローラ側では、ルートを整理するためのいくつかの変更があります。また、ルーティングエンジンの内部変更により、複雑なアプリケーションでのメモリ使用量が低下します。

6.1 浅いルートのネスト

浅いルートのネストは、深くネストされたリソースの使用の難しさに対する解決策を提供します。浅いネストでは、作業するリソースを一意に識別するために十分な情報を提供するだけで済みます。

map.resources :publishers, :shallow => true do |publisher|
  publisher.resources :magazines do |magazine|
    magazine.resources :photos
  end
end

これにより、次のようなルートが認識されるようになります。

/publishers/1           ==> publisher_path(1)
/publishers/1/magazines ==> publisher_magazines_path(1)
/magazines/2            ==> magazine_path(2)
/magazines/2/photos     ==> magazines_photos_path(2)
/photos/3               ==> photo_path(3)

6.2 メンバーまたはコレクションルートのメソッド配列

新しいメンバーまたはコレクションルートには、メソッドの配列を指定することができます。これにより、1つ以上のメソッドを処理する必要がある場合に、ルートをすぐに任意の動詞を受け入れるように定義する必要がなくなります。Rails 2.2では、次のような正当なルート宣言が可能です。

map.resources :photos, :collection => { :search => [:get, :post] }

6.3 特定のアクションを持つリソース

デフォルトでは、map.resourcesを使用してルートを作成すると、Railsは7つのデフォルトアクション(index、show、create、new、edit、update、destroy)のためのルートを生成します。しかし、これらのルートはアプリケーションのメモリを使用し、Railsに追加のルーティングロジックを生成させます。これからは、:only:exceptオプションを使用して、Railsがリソースに対して生成するルートを細かく調整することができます。単一のアクション、アクションの配列、または特別な:allまたは:noneオプションを指定することができます。これらのオプションはネストされたリソースにも継承されます。

map.resources :photos, :only => [:index, :show]
map.resources :products, :except => :destroy

6.4 その他のアクションコントローラの変更

  • リクエストのルーティング中に発生した例外のために、簡単にカスタムエラーページを表示できるようになりました。
  • HTTP Acceptヘッダーはデフォルトで無効になっています。必要なフォーマットを示すために、/customers/1.xmlなどのフォーマット指定のURLの使用を推奨します。Acceptヘッダーが必要な場合は、config.action_controller.use_accept_header = trueで再度有効にできます。
  • ベンチマークの数値は、秒の小数部分ではなくミリ秒で報告されるようになりました。
  • Railsは今ではHTTP専用のクッキー(およびセッションに使用)をサポートしており、新しいブラウザでのいくつかのクロスサイトスクリプティングのリスクを軽減します。
  • redirect_toは、URIスキームを完全にサポートするようになりました(たとえば、svnssh: URIにリダイレクトすることができます)。
  • renderは、適切なMIMEタイプでプレーンなバニラJavaScriptをレンダリングするための:jsオプションをサポートしています。
  • リクエスト偽装保護は、HTML形式のコンテンツリクエストにのみ適用されるように厳密化されました。
  • ポリモーフィックURLは、渡されたパラメータがnilの場合にもより適切に動作します。たとえば、nilの日付でpolymorphic_path([@project, @date, @area])を呼び出すと、project_area_pathが返されます。

7 Action View

  • javascript_include_tagstylesheet_link_tagは、:allと一緒に使用するための新しい:recursiveオプションをサポートしています。これにより、1行のコードでファイルのツリー全体をロードすることができます。
  • 含まれるPrototype JavaScriptライブラリがバージョン1.6.0.3にアップグレードされました。
  • RJS#page.reloadを使用して、JavaScriptを介してブラウザの現在の場所をリロードできます。
  • atom_feedヘルパーは、XML処理命令を挿入するための:instructオプションを受け入れるようになりました。

8 Action Mailer

Action Mailerは、メーラーレイアウトをサポートするようになりました。適切に名前付けられたレイアウト(たとえば、CustomerMailerクラスはlayouts/customer_mailer.html.erbを使用することを期待します)を提供することで、HTMLメールをブラウザのビューと同じように美しくすることができます。

Action Mailerは、GMailのSMTPサーバーをサポートし、自動的にSTARTTLSをオンにするようになりました。これにはRuby 1.8.7のインストールが必要です。

9 Active Support

Active Supportは、Railsアプリケーション向けのビルトインのメモ化、each_with_objectメソッド、デリゲートに対するプレフィックスサポート、およびその他の新しいユーティリティメソッドを提供します。

9.1 メモ化

メモ化は、メソッドを一度だけ初期化し、その値を繰り返し使用するために保管するパターンです。おそらく、自分のアプリケーションでこのパターンを使用したことがあるかもしれません。

def full_name
  @full_name ||= "#{first_name} #{last_name}"
end

メモ化を使用すると、このタスクを宣言的な方法で処理できます。

extend ActiveSupport::Memoizable

def full_name
  "#{first_name} #{last_name}"
end
memoize :full_name

メモ化の他の機能には、unmemoizeunmemoize_allmemoize_allがあり、メモ化をオンまたはオフにするために使用できます。 * 主な寄稿者:Josh Peek * 追加情報: * Edge Railsの新機能:簡単なメモ化 * メモ化とは?メモ化のガイド

9.2 each_with_object

each_with_objectメソッドは、Ruby 1.9からバックポートされたメソッドを使用して、injectの代替手段を提供します。このメソッドは、現在の要素とメモをブロックに渡しながら、コレクションを反復処理します。

%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } # => {'foo' => 'FOO', 'bar' => 'BAR'}

主な寄稿者:Adam Keys

9.3 プレフィックス付きデリゲート

あるクラスから別のクラスに振る舞いを委譲する場合、デリゲートされたメソッドを識別するためにプレフィックスを指定することができます。例えば:

class Vendor < ActiveRecord::Base
  has_one :account
  delegate :email, :password, :to => :account, :prefix => true
end

これにより、vendor#account_emailvendor#account_passwordというデリゲートされたメソッドが生成されます。カスタムプレフィックスも指定できます:

class Vendor < ActiveRecord::Base
  has_one :account
  delegate :email, :password, :to => :account, :prefix => :owner
end

これにより、vendor#owner_emailvendor#owner_passwordというデリゲートされたメソッドが生成されます。

主な寄稿者:Daniel Schierbeck

9.4 その他のActive Supportの変更

  • ActiveSupport::Multibyteの大幅な更新(Ruby 1.9との互換性の修正を含む)
  • ActiveSupport::Rescuableの追加により、任意のクラスでrescue_from構文を使用できるようになりました。
  • DateおよびTimeクラスのpast?today?future?を追加し、日付/時間の比較を容易にしました。
  • Array#secondからArray#fifthまでのエイリアスとしてArray#[1]からArray#[4]を追加しました。
  • Enumerable#many?は、collection.size > 1をカプセル化します。
  • Inflector#parameterizeは、入力のURL用バージョンを生成し、to_paramで使用できます。
  • Time#advanceは、小数点以下の日数と週数を認識するため、1.7.weeks.ago1.5.hours.sinceなどが可能です。
  • 含まれるTzInfoライブラリは、バージョン0.3.12にアップグレードされました。
  • ActiveSupport::StringInquirerは、文字列の等価性をテストするためのきれいな方法を提供します:ActiveSupport::StringInquirer.new("abc").abc? => true

10 Railties

Railties(Rails自体のコアコード)では、config.gemsメカニズムに最も大きな変更があります。

10.1 config.gems

デプロイメントの問題を回避し、Railsアプリケーションをより自己完結型にするために、Railsアプリケーションが必要とするすべてのgemのコピーを/vendor/gemsに配置することができます。この機能はRails 2.1で初めて登場しましたが、Rails 2.2ではより柔軟で堅牢になり、gem間の複雑な依存関係を処理します。Railsにおけるgemの管理には、次のコマンドが含まれます:

  • config.gem _gem_name_config/environment.rbファイル内):設定されたすべてのgemと、それら(およびその依存関係)がインストールされているか、凍結されているか、フレームワーク(フレームワークgemは、gemの依存関係コードが実行される前にRailsによってロードされるgemです。このようなgemは凍結できません)を一覧表示します。
  • rake gems:コンピュータに不足しているgemをインストールします。
  • rake gems:unpack:必要なgemのコピーを/vendor/gemsに配置します。
  • rake gems:unpack:dependencies:必要なgemとその依存関係のコピーを/vendor/gemsに取得します。
  • rake gems:build:不足しているネイティブ拡張をビルドします。
  • rake gems:refresh_specs:Rails 2.1で作成されたベンダーgemをRails 2.2の保存方法に合わせるために、ベンダーgemを更新します。

コマンドラインでGEM=_gem_name_を指定することで、単一のgemを展開またはインストールすることができます。

10.2 その他のRailtiesの変更

  • Thinウェブサーバーのファンであれば、script/serverが直接Thinをサポートすることを知って喜ぶでしょう。
  • script/plugin install &lt;plugin&gt; -r &lt;revision&gt;は、gitベースのプラグインとsvnベースのプラグインの両方で動作します。
  • script/consoleは、--debuggerオプションをサポートします。
  • Rails自体をビルドするための継続的インテグレーションサーバーの設定手順がRailsソースに含まれています。
  • rake notes:custom ANNOTATION=MYFLAGを使用して、カスタム注釈をリストアップすることができます。
  • Rails.envStringInquirerでラップし、Rails.env.development?のように使用できるようにしました。
  • 廃止の警告を排除し、gemの依存関係を適切に処理するために、Railsはrubygems 1.3.1以上を必要とします。

11 廃止予定

このリリースでは、いくつかの古いコードが廃止されています:

  • Rails::SecretKeyGeneratorActiveSupport::SecureRandomに置き換えられました。
  • render_componentは廃止されました。この機能が必要な場合は、render_componentsプラグインを使用できます。
  • パーシャルをレンダリングする際の暗黙のローカル代入は廃止されました。

    def partial_with_implicit_local_assignment
      @customer = Customer.new("Marcel")
      render :partial => "customer"
    end
    

    以前のコードでは、パーシャル「customer」内でcustomerというローカル変数が利用可能でした。現在は、すべての変数を明示的に:localsハッシュを介して渡す必要があります。

  • country_selectは削除されました。詳細情報やプラグインの代替方法については、非推奨ページを参照してください。

  • ActiveRecord::Base.allow_concurrencyはもはや効果を持ちません。

  • ActiveRecord::Errors.default_error_messagesは非推奨となり、代わりにI18n.translate('activerecord.errors.messages')を使用してください。

  • 国際化のための%sおよび%dの補間構文は非推奨です。

  • String#charsは非推奨となり、String#mb_charsを使用してください。

  • 小数点以下の月や年の期間は非推奨です。代わりにRubyのDateおよびTimeクラスの算術を使用してください。

  • Request#relative_url_rootは非推奨です。代わりにActionController::Base.relative_url_rootを使用してください。

12 クレジット

リリースノートはMike Gunderloyによって編集されました。

フィードバック

このガイドの品質向上にご協力ください。

タイポや事実の誤りを見つけた場合は、ぜひ貢献してください。 開始するには、ドキュメントへの貢献セクションを読んでください。

不完全なコンテンツや最新でない情報も見つかるかもしれません。 メインのドキュメントに不足しているドキュメントを追加してください。 修正済みかどうかは、まずEdge Guidesを確認してください。 スタイルと規約については、Ruby on Rails Guides Guidelinesを確認してください。

修正すべき点を見つけたが、自分で修正できない場合は、 問題を報告してください

そして最後に、Ruby on Railsのドキュメントに関するあらゆる議論は、公式のRuby on Railsフォーラムで大歓迎です。