1 インフラストラクチャ
Rails 2.2 は、Rails をスムーズに動作させ、他のシステムと接続するためのインフラストラクチャにとって重要なリリースです。
1.1 国際化
Rails 2.2 は、国際化(または i18n)のための簡単なシステムを提供します。
- 主な貢献者: Rails i18 チーム
- 詳細情報 :
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 ページには以下が含まれています。
- Rails のはじめ方
- Rails データベースマイグレーション
- Active Record 関連付け
- Active Record クエリインターフェース
- Rails でのレイアウトとレンダリング
- Action View フォームヘルパー
- Rails ルーティングの基本
- Action Controller の概要
- Rails キャッシュ
- Rails アプリケーションのテストガイド
- Rails アプリケーションのセキュリティ
- Rails アプリケーションのデバッグ
- Rails プラグインの基本
全体で、Guides は初心者から中級者の Rails 開発者に対して数万語のガイダンスを提供しています。
これらのガイドをローカルで生成するには、アプリケーション内で次のコマンドを実行します。
$ rake doc:guides
これにより、ガイドが Rails.root/doc/guides
内に配置され、お気に入りのブラウザで Rails.root/doc/guides/index.html
を開くことで直接閲覧できます。
- Xavier Noria と Hongli Lai からの主な貢献
- 詳細情報:
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.yml
にpool
キーを追加して調整することもできます)まで成長します。これにより、多くの同時ユーザをサポートするアプリケーションのボトルネックが解消されます。また、ギブアップする前の待機タイムアウトはデフォルトで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')
- 主な貢献者:Emilio Tagua
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')
- 主な貢献者:Josh Susser
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
もオーバーライドする必要があります。
- 主な貢献者:Adam Milligan
- 詳細情報:
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)
- 主な貢献者:S. Brent Faulkner
- 詳細情報:
6.2 メンバーまたはコレクションルートのメソッド配列
新しいメンバーまたはコレクションルートには、メソッドの配列を指定することができます。これにより、1つ以上のメソッドを処理する必要がある場合に、ルートをすぐに任意の動詞を受け入れるように定義する必要がなくなります。Rails 2.2では、次のような正当なルート宣言が可能です。
map.resources :photos, :collection => { :search => [:get, :post] }
- 主な貢献者:Brennan Dunn
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
- 主な貢献者:Tom Stuart
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_tag
とstylesheet_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
メモ化の他の機能には、unmemoize
、unmemoize_all
、memoize_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_email
とvendor#account_password
というデリゲートされたメソッドが生成されます。カスタムプレフィックスも指定できます:
class Vendor < ActiveRecord::Base
has_one :account
delegate :email, :password, :to => :account, :prefix => :owner
end
これにより、vendor#owner_email
とvendor#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.ago
、1.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を展開またはインストールすることができます。
- 主な寄稿者:Matt Jones
- 追加情報:
10.2 その他のRailtiesの変更
- Thinウェブサーバーのファンであれば、
script/server
が直接Thinをサポートすることを知って喜ぶでしょう。 script/plugin install <plugin> -r <revision>
は、gitベースのプラグインとsvnベースのプラグインの両方で動作します。script/console
は、--debugger
オプションをサポートします。- Rails自体をビルドするための継続的インテグレーションサーバーの設定手順がRailsソースに含まれています。
rake notes:custom ANNOTATION=MYFLAG
を使用して、カスタム注釈をリストアップすることができます。Rails.env
をStringInquirer
でラップし、Rails.env.development?
のように使用できるようにしました。- 廃止の警告を排除し、gemの依存関係を適切に処理するために、Railsはrubygems 1.3.1以上を必要とします。
11 廃止予定
このリリースでは、いくつかの古いコードが廃止されています:
Rails::SecretKeyGenerator
はActiveSupport::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フォーラムで大歓迎です。