Rails 2.3では、Rackの広範な統合、Railsエンジンのサポートの刷新、Active Recordのネストされたトランザクション、ダイナミックスコープとデフォルトスコープ、統一レンダリング、より効率のよいルーティング、アプリケーションテンプレート、静かなバックトレースといったさまざまな新機能や改善機能が提供されています。このリストは主要なアップグレードをカバーしていますが、すべての小さなバグフィックスや変更を含んでいるわけではありません。すべてを見たい場合は、GitHubのメインRailsリポジトリのコミットリスト をチェックするか、個別のRailsコンポーネントの CHANGELOG
ファイルを確認してください。
Railsアプリケーションのアーキテクチャには、モジュール式WebサーバインターフェースであるRackの完全統合と、Railsエンジンの新たなサポートという2つの大きな変更があります。
Railsは、これまでのCGIと決別し、あらゆる場所でRackを使うようになりました。このため、非常に多くの内部変更が必要となり、その結果、Railsはプロキシインタフェースを通じてCGIをサポートするようになりました(ただし、CGIを使っている人も心配ありません)。それでも、これはRails内部に対する大きな変更です。2.3にアップグレードしたら、ローカル環境と本番環境でテストする必要があります。以下などについてテストが必要です。
以下はRack関連の変更点の概要です。
script/server
は rackup 設定ファイルが存在すれば、それを取得します。これは Rack と互換性のある全てのサーバをサポートすることを意味します。デフォルトでは config.ru
ファイルを探索しますが、-c
スイッチでこれを上書きできます。ActionController::Dispatcher
は独自のデフォルトミドルウェアスタックを保持しています。ミドルウェアは注入・並べ替え・削除できます。ミドルウェアスタックは起動時にチェーンにコンパイルされます。ミドルウェアスタックは environment.rb
で設定できます。rake middleware
タスクが追加されました。これはミドルウェアスタックの読み込み順序をデバッグするのに便利です。ActionController::CGIHandler
は Rack の後方互換性のある CGI ラッパーです。CGIHandler
は古い CGI オブジェクトを受け取り、その環境情報を Rack と互換性のある形に変換します。CgiRequest
と CgiResponse
は削除されました。CGI::Cookie.new
が不要になりました。request.cookies["foo"]
にString
値を代入すれば期待どおりcookieが設定されます。CGI::Session::CookieStore
が ActionController::Session::CookieStore
に置き換えられました。CGI::Session::MemCacheStore
が ActionController::Session::MemCacheStore
に置き換えられました。CGI::Session::ActiveRecordStore
が ActiveRecord::SessionStore
に置き換えられました。ActionController::Base.session_store = :active_record_store
で変更できます。ActionController::Base.session = { :key => "..." }
で設定できます。ただし :session_domain
オプション名は :domain
に変更されました。ActionController::Lock
ミドルウェアに移動しました。ActionController::AbstractRequest
と ActionController::Request
は統合されました。新しい ActionController::Request
は Rack::Request
を継承しています。これは、テストリクエストにおける response.headers['type']
へのアクセスに影響します。代わりに response.content_type
をお使いください。ActiveRecord::QueryCache
ミドルウェアは、 ActiveRecord
がロードされると自動的にミドルウェアスタックに挿入されます。このミドルウェアは、リクエストごとの Active Record クエリキャッシュのセットアップやクリアを行います。SomeController.call(env)
を使います。ルータはルーティングパラメータを rack.routing_args
に保存します。ActionController::Request
は Rack::Request
を継承するようになりました。config.action_controller.session = { :session_key => 'foo', ...
の代わりに、 config.action_controller.session = { :key => 'foo', ...
をお使い下さい。ParamsParser
を使うと、XML、JSON、または YAML リクエストを前処理して、任意の Rack::Request
オブジェクトで正常に読み込めるようになりました。ここしばらくアップグレードがありませんでしたが、Rails 2.3ではRailsエンジン(他のアプリケーションに組み込めるRailsアプリケーション)にいくつかの新機能が追加されました。まず、エンジン内のルーティングファイルは routes.rb
ファイルと同様に自動的にロード・リロードされるようになりました(これは他のプラグイン内のルーティングファイルについても同様です)。次に、プラグインにappフォルダがある場合、app/[models|controllers|helpers]
は自動的にRailsの読み込みパスに追加されます。エンジンもビューパスの追加をサポートするようになり、Action MailerやAction Viewはエンジンや他のプラグインからのビューを利用するようになりました。
RailsガイドプロジェクトはRails 2.3向けにガイドをいくつも追加しました。さらに、edgeguides.rubyonrails.orgという別サイトでエッジRailsのガイド(英語のみ)を参照できるようになりました。また、ドキュメント関連ではRails wikiやRails Bookの再立ち上げなども行われました(訳注: Rails wikiとRails Bookは現在は動いていません)。
Rails 2.3は、Ruby 1.8および現在リリースされているRuby 1.9.1のどちらでも、独自のテストにすべてパスするはずです。ただし1.9.1への移行には、Railsコアだけでなく、データアダプタ、プラグイン、その他依存するコードのすべてをRuby 1.9.1互換性でチェックする必要があることにご注意下さい。
Rails 2.3のActive Recordでは、非常に多くの新機能追加とバグフィックスが施されています。特に、ネステッド属性、ネステッドトランザクション、動的スコープとデフォルトスコープ、およびバッチ処理がハイライトです。
Active Recordは、モデルのネステッド属性を以下のように直接更新できるようになりました。
class Book < ActiveRecord::Base has_one :author has_many :pages accepts_nested_attributes_for :author, :pages end
ネステッド属性を有効にすると、レコードと関連する子レコードを自動的に(かつアトミックに)保存し、子を意識したバリデーションを行い、ネステッドフォームをサポートします(後述)。
また、:reject_if
オプションを使うことで、ネステッド属性によって追加される新しいレコードに対する要件を指定することもできます。
accepts_nested_attributes_for :author, :reject_if => proc { |attributes| attributes['name'].blank? }
要望の多かったネステッドトランザクションがActive Recordでサポートされました。これで以下のようなコードを書けるようになりました。
User.transaction do User.create(:username => 'Admin') User.transaction(:requires_new => true) do User.create(:username => 'Regular') raise ActiveRecord::Rollback end end User.find(:all) # => Adminだけを返す
ネステッドトランザクションでは、外側のトランザクションの状態に影響を与えずに内側のトランザクションをロールバックできます。トランザクションをネストしたい場合は、明示的に :requires_new
オプションを追加する必要があります。そうしないと、ネステッドトランザクションは単に親トランザクションの一部になります(現在のRails 2.2ではそうなっています)。ネステッドトランザクションは内部で セーブポイントを使う ので、真のネステッドトランザクションを持たないデータベースでもサポートされます。また、テスト中にこれらのトランザクションをトランザクションフィクスチャでうまく動作させるために、ちょっとしたマジックも使っています。
Railsのダイナミックファインダーメソッド(find_by_color_and_flavor
のような動的に生成されるメソッド)や名前付きスコープ(再利用可能なクエリ条件をcurrently_active
のようにフレンドリーな名前にカプセル化できる)は既にご存知でしょう。これらに加えて動的なスコープメソッドも使えるようになりました。このアイデアは、以下のように動的なフィルタリングやメソッドチェインを可能にする構文をまとめることです。
Order.scoped_by_customer_id(12) Order.scoped_by_customer_id(12).find(:all, :conditions => "status = 'open'") Order.scoped_by_customer_id(12).scoped_by_status("open")
動的スコープは、何も定義せずにすぐ使えます。
Rails 2.3では、名前付きスコープに似たデフォルトスコープという概念が導入されます。これはモデル内のすべての名前付きスコープやfindメソッドに適用されます。たとえば、default_scope :order => 'name ASC'
と書けば、そのモデルからレコードを取得するときはいつでも名前順でソートされて出力されます(もちろん、このオプションをオーバーライドしない限り)。
find_in_batches
を使うことで、メモリに負担をかけずにActive Record モデルの大量のレコードを処理できるようになりました。
Customer.find_in_batches(:conditions => {:active => true}) do |customer_group| customer_group.each { |customer| customer.update_account_balance! } end
find_in_batches
には、ほとんどの find
オプションを渡せます。ただし、返すレコードの順序を指定することや (常に主キーの昇順で返される整数値でなければなりません)、 :limit
オプションを使うことはできません。代わりに、 :batch_size
オプション (デフォルトは 1000件) を使用して、各バッチで返されるレコードの数を設定できます。
新しい find_each
メソッドは、個々のレコードを返す find_in_batches
のラッパーで、検索自体はバッチ処理で行われます (デフォルトでは 1000 件) 。
Customer.find_each do |customer| customer.update_account_balance! end
この方法はバッチ処理でのみ使うようご注意ください。少数のレコード(1000件以下)の場合は、通常のfindメソッドをループで回してください。
each
と呼ばれていました)。
Active Record コールバックを使うときに、同じコールバックで :if
と :unless
オプションを組み合わせ、複数の条件を配列として指定できるようになりました。
before_save :update_credit_rating, :if => :active, :unless => [:admin, :cash_only]
having
で検索:having
オプション(および has_many
と has_and_belongs_to_many
関連付け)が追加され、グループ化された検索結果のレコードを検索でフィルタできるようにました。SQL の知識が豊富な人ならご存知のように、グループ化された結果に基づいてフィルタをかけられるようになります。
developers = Developer.find(:all, :group => "salary", :having => "sum(salary) > 10000", :select => "salary")
MySQLコネクションで再接続フラグをサポートされました。trueに設定すると、コネクションが切れてあきらめる前にクライアントがサーバーへの再接続を試みます。Railsアプリケーションでこの動作を有効にするために、database.yml
でMySQL接続に reconnect = true
を設定できるようになりました。デフォルトは false
なので、既存のアプリケーションの動作は変わりません。
has_and_belongs_to_many
プリロードの生成 SQL から余分な AS
が削除され、いくつかのデータベースの動作が改善されました。ActiveRecord::Base#new_record?
は、既存のレコードが存在する場合に nil
ではなく false
を返すようになりました。has_many :through
の関連付けにおいて、テーブル名の引用符のバグが修正されました。updated_at
タイムスタンプに特定のタイムスタンプを指定できるようになりました: cust = Customer.create(:name => "ABC Industries", :updated_at => 1.day.ago)
.find_by_attribute!
呼び出しに失敗した場合のエラーメッセージを改善しました。to_xml
サポートに :camelize
オプションが追加され、柔軟性が少し高まりました。before_update
や before_create
のコールバックをキャンセルする際のバグが修正されました。validates_length_of
は、 :in
または :within
オプション (オプションが指定された場合) でカスタムエラーメッセージを使うようになりました。Account.scoped(:select => "DISTINCT credit_limit").count
のようなことができるようになりました。ActiveRecord::Base#invalid?
が ActiveRecord::Base#valid?
の逆として動作するようになりました。Action Controllerは、今回のリリースでレンダリングに関する大幅な変更と、ルーティングなどの改善を行いました。
ActionController::Base#render
でレンダリング対象を指定する方法がよりスマートになりました。レンダリング対象を指定するだけで、正しい結果が期待できます。以前のバージョンのRailsでは、以下のようにレンダリングで明示的な情報を提供する必要が生じることがよくありました。
render :file => '/tmp/random_file.erb' render :template => 'other_controller/action' render :action => 'show'
Rails 2.3では以下のように、レンダリングしたいものを指定するだけで済みます。
render '/tmp/random_file.erb' render 'other_controller/action' render 'show' render :show
Railsは、レンダリング対象の冒頭にスラッシュがある場合、スラッシュが途中にある場合、スラッシュがまったくない場合に応じて、ファイル、テンプレート、アクションのいずれかを選択します。アクションをレンダリングするときに、文字列の代わりにシンボルも使えます。その他のレンダリングスタイル (:inline
, :text
, :update
, :nothing
, :json
, :xml
, :js
) では、引き続き明示的なオプションが必要です。
application.rb
で特殊なケースのネーミングにいつも悩まされている方へ朗報です。Rails 2.3ではapplication_controller.rb
という名前に代わりました。さらに、新しい rake タスク rake rails:update:application_controller
が用意され、これを自動的に実行できます(これは通常の rake rails:update
プロセスの一部として実行されます)。
Railsでは、HTTPダイジェスト認証がビルトインでサポートされるようになりました。これを使うには、以下のようにユーザーのパスワードを返すブロックを付けて authenticate_or_request_with_http_digest
を呼び出します(パスワードはハッシュ化され、送信されたcredentialと比較されます)。
class PostsController < ApplicationController Users = {"dhh" => "secret"} before_filter :authenticate def secret render :text => "Password Required!" end private def authenticate realm = "Application" authenticate_or_request_with_http_digest(realm) do |name| Users[name] end end end
Rails 2.3では、ルーティングにいくつかの重要な変更が加えられています。formatted_
ルーティングヘルパーがなくなり、代わりに :format
をオプションとして渡せるようになりました。これにより、どのリソースに対してもルート生成プロセスが50%削減され、かなりの量のメモリが節約できます(大規模なアプリケーションでは最大100MB)。自分のコードが formatted_
ヘルパーを使っていたとしても、当面は動作しますが、この動作は非推奨であり、新しい標準でルーティングを書き直せば、アプリケーションの効率は向上します。もう一つの大きな変更点は、Railsが routes.rb
だけでなく、複数のルーティングファイルをサポートするようになったことです。RouteSet#add_configuration_file
を使えば、現在読み込まれているルーティングをクリアすることなく、いつでも新しいルートを取り込めます。この変更はRailsエンジンで最も有用ですが、ルーティングをバッチで一括読み込みする必要がある任意のアプリケーションで利用できます。
大きな変更点として、Action Controller のセッションストレージの基盤が Rack レベルに押し下げられたことが挙げられます。Railsアプリケーションからはまったく見えないはずですが、コードにはかなりの作業が含まれています(ボーナスとして、古いCGIセッションハンドラ周辺の厄介なパッチがいくつか削除されました)。Rails以外のRackアプリケーションもRailsアプリケーションと同じセッションストレージハンドラにアクセスできる (つまり同じセッションにアクセスできる) からです。さらに、セッションは遅延読み込みされるようになりました(フレームワークの他の部分の読み込み改善と同様)。つまり、セッションが不要な場合に明示的に無効にする必要はなくなりました。セッションを参照しないようにすれば、セッションは読み込まれません。
RailsでMIMEタイプを処理するコードには、いくつかの変更があります。まず、 MIME::Type
が =~
演算子を実装し、同義語を持つタイプの存在をチェックする必要がある場合の記法がずっと明確になりました。
if content_type && Mime::JS =~ content_type # 何かする end Mime::JS =~ "text/javascript" => true Mime::JS =~ "application/javascript" => true
もう1つの変更は、フレームワークがさまざまな場所でJavaScriptをチェックするときに Mime::JS
を使うようになり、それらの代替をきれいに処理できるようになったことです。
respond_to
の最適化RailsとMerbチームの合併による最初の成果として、Rails 2.3にはrespond_to
メソッドの最適化が含まれています。このメソッドはもちろん多くのRailsアプリケーションで多用されていて、送られてきたリクエストのMIMEタイプに応じてコントローラが異なる結果をフォーマットできるようになっています。method_missing
の呼び出しをなくし、プロファイリングと微調整を行った結果、3つのフォーマットを切り替えるシンプルな respond_to
で、1秒あたりのリクエスト数が8%向上しています。最も優れている点は、このスピードアップを利用するためにアプリケーションのコードを変更する必要がまったくないことです。
Railsは、リモートキャッシュストアから読み込んだデータをリクエストごとにローカルキャッシュとして保持するようになり、不要な読み込みを減らしてサイトのパフォーマンスを向上させました。この機能はもともと MemCacheStore
に限定されていましたが、必要なメソッドを実装しているリモートストアであれば、どのストアでも利用できます。
Railsは、設定したロケールに応じてローカライズされたビューを提供できるようになりました。たとえば、 Posts
コントローラに show
アクションがあると、デフォルトではapp/views/posts/show.html.erb
がレンダリングされます。しかしI18n.locale = :da
と設定すると、 app/views/posts/show.da.html.erb
がレンダリングされるようになります。ローカライズされたテンプレートが存在しない場合は、装飾なしバージョンが使われます。Railsには I18n#available_locales
と I18n::SimpleBackend#available_locales
もあり、これらは現在のRailsプロジェクトで利用可能な翻訳の配列を返します。
さらに、同じ方法でpublicディレクトリにあるrescueファイルもローカライズできます。たとえば、 public/500.da.html
や public/404.en.html
が使えるようになります。
翻訳APIの変更により、パーシャル内のキー翻訳を簡単に書けるようになり、記述の重複が少なくなりました。people/index.html.erb
テンプレートから translate(".foo")
を呼び出すと、実際には I18n.translate("people.index.foo")
を呼び出します。キーの前にピリオドがない場合は、以前と同じようにAPIはスコープなしとなります。
send_file
でファイルを送信するときに、Rails は ETag ヘッダの送信をスキップするようになりました。ActionController::Base.ip_spoofing_check = false
と設定することで、チェックを完全に無効にできるようになりました。ActionController::Dispatcher
は独自のミドルウェアスタックを実装しており、 rake middleware
を実行することで確認できます。send_file
と send_data
の :type
オプションで、send_file("fabulous.png", :type => :png)
のようにシンボルを使えるようになりました。map.resources
の :only
と :except
オプションは、ネストしたリソースには継承されなくなりました。expires_in
、stale?
、fresh_when
メソッドに :public
オプションを指定できるようになりました。:requirements
オプションが正しく動作するようになりました。polymorphic_url
が、不規則に活用される複数形の名前を持つオブジェクトをより適切に扱えるようになりました。Rails 2.3のAction Viewでは、ネステッドモデルのフォーム、render
の改善、日付選択ヘルパーのより柔軟な表示、アセットキャッシングの高速化などが行われました。
親モデルが子オブジェクトのネステッド属性を受け入れる場合(上述のActive Recordのセクションの説明を参照)、 form_for
と field_for
を使ってネステッドフォームを作成できます。これらのフォームは任意の深さにネスト可能で、少ないコードで複雑なオブジェクト階層を単一のビューで編集できます。たとえば以下のようなモデルがあるとします。
class Customer < ActiveRecord::Base has_many :orders accepts_nested_attributes_for :orders, :allow_destroy => true end
Rails 2.3では以下のようにビューを書けます。
<% form_for @customer do |customer_form| %> <div> <%= customer_form.label :name, 'Customer Name:' %> <%= customer_form.text_field :name %> </div> <!-- Here we call fields_for on the customer_form builder instance. The block is called for each member of the orders collection. --> <% customer_form.fields_for :orders do |order_form| %> <p> <div> <%= order_form.label :number, 'Order Number:' %> <%= order_form.text_field :number %> </div> <!-- The allow_destroy option in the model enables deletion of child records. --> <% unless order_form.object.new_record? %> <div> <%= order_form.label :_delete, 'Remove:' %> <%= order_form.check_box :_delete %> </div> <% end %> </p> <% end %> <%= customer_form.submit %> <% end %>
render
メソッドは年々賢くなり、今はさらに賢くなりました。オブジェクトやコレクションと適切なパーシャルがあり、命名が一致する場合は、オブジェクトをrender
するだけで動くようになりました。たとえばRails 2.3では、以下のrender
コールがビューで使えます(命名が適切であると仮定します)。
# これは以下と同様 # render :partial => 'articles/_article', :object => @article render @article # これは以下と同様 # render :partial => 'articles/_article', :collection => @articles render @articles
Rails 2.3では、様々な日付選択ヘルパー(date_select
、time_select
、datetime_select
)で、コレクション選択ヘルパーと同様にカスタムプロンプトを指定できます。プロンプトには、文字列の他に、様々なコンポーネントのプロンプト文字列のハッシュを渡せます。また、 :prompt
を true
に設定することで、一般的なプロンプトも利用できます。
select_datetime(DateTime.now, :prompt => true) select_datetime(DateTime.now, :prompt => "Choose date and time") select_datetime(DateTime.now, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year', :hour => 'Choose hour', :minute => 'Choose minute'})
静的アセットパスに「キャッシュバスター」としてタイムスタンプを追加するRailsの慣習はよく知られていると思います。これは、画像やスタイルシートなどの古いコピーが、サーバーで変更されたときにユーザーのブラウザのキャッシュから提供されないようにするためのものです。Action Viewの設定オプション cache_asset_timestamps
で、この動作を変更できるようになりました。キャッシュを有効にすると、Railsは最初にアセットを提供するときにタイムスタンプを一度算出して値を保存します。これは、静的アセットを提供するための(コストのかかる)ファイルシステム呼び出しが減ることを意味しますが、その代わり、サーバーの実行中にアセットを変更しても変更がクライアントに反映されることも期待できなくなります。
エッジRailsでは、アセットホストを「呼び出しに応答する特定のオブジェクト」として宣言できるようになり、アセットホストの柔軟性が高まりました。これにより、アセットホストで必要などんな複雑なロジックも実装できるようになります。
grouped_options_for_select
ヘルパーメソッドアクションビューには、セレクタボックスの生成を支援するヘルパーがすでにたくさんありますが、もうひとつ増えました。grouped_options_for_select
です。これは以下のように、文字列の配列またはハッシュを受け取って、 option
タグを optgroup
タグでラップした文字列に変換するものです。
grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], "Cowboy Hat", "Choose a product...")
上は以下を返します。
<option value="">Choose a product...</option> <optgroup label="Hats"> <option value="Baseball Cap">Baseball Cap</option> <option selected="selected" value="Cowboy Hat">Cowboy Hat</option> </optgroup>
フォームのセレクタヘルパー(select
や options_for_select
など)が:disabled
オプションをサポートするようになり、結果のタグで無効にしたい単一の値または値の配列を受け取れるようになりました。
select(:post, :category, Post::CATEGORIES, :disabled => 'private')
上は以下を返します。
<select name="post[category]"> <option>story</option> <option>joke</option> <option>poem</option> <option disabled="disabled">private</option> </select>
また、無名関数を使えば、コレクションからどのオプションを選択または無効にするかを実行時に決定することもできます。
options_from_collection_for_select(@product.sizes, :name, :id, :disabled => lambda{|size| size.out_of_stock?})
Rails 2.3では、キャッシュされたテンプレートを特定の環境で有効または無効にする機能があります。キャッシュされたテンプレートは、レンダリング時に新しいテンプレートファイルがあるかどうかをチェックしないので、速度が向上します。しかし、これは同時に、サーバを再起動せずに「その場で」テンプレートを置き換えられないということでもあります。
ほとんどの場合、production環境ではテンプレートのキャッシュを有効にしたいと思うでしょう。これは production.rb
ファイルで設定します。
config.action_view.cache_template_loading = true
上の設定は、新しいRails 2.3アプリケーションではデフォルトで生成されます。古いバージョンのRailsからアップグレードした場合、Railsはproduction環境とtest環境ではテンプレートをキャッシュするようにデフォルトで設定しますが、development環境では設定しません。
ActiveSupport::SecureRandom
によって生成されたシンプルなランダム文字列を使うようになりました。auto_link
が、生成されたメールのリンクにオプション(:target
や :class
など)を適切に適用するようになりました。autolink
ヘルパーがリファクタリングされ、より直感的に使えるようになりました。current_page?
が正しく動作するようになりました。Active Supportでも、Object#try
などいくつかの興味深い変更が行われました。
Object#try
多くの人が、オブジェクトに対する操作を試みるときにtry()
を使うというアイデアを採用しています。特にビューでは、<%= @person.try(:name) %>
のようなコードを書くことでnilチェックを回避できるので便利です。この機能がRailsに組み込まれました。Railsに実装されたこの機能は、privateメソッドに対して NoMethodError
を発生し、オブジェクトがnilの場合は常に nil
を返します。
Object#tap
のバックポートObject#tap
は Ruby 1.9 および 1.8.7 に追加されたもので、Rails に以前からある returning
メソッドに似ています。ブロックをyield
して、yield
したオブジェクトを返すというものです。Railsは現在、これを古いバージョンのRubyでも使えるようにするコードを含んでいます。
Active SupportのXML解析サポートで、パーサーを別のものに差し替えられるようになり、柔軟性が増しました。デフォルトでは、標準的なREXMLの実装を使用しますが、適切なgemがインストールされていれば、高速なLibXMLやNokogiriの実装を自分のアプリケーションに簡単に指定できます。
XmlMini.backend = 'LibXML'
TimeWithZone
で秒以下をサポートTime
クラスと TimeWithZone
クラスに、時刻を XML フレンドリーな文字列で返す xmlschema
メソッドが含まれました。Rails 2.3 のTimeWithZone
は Time
と同じ引数になり、返される文字列の小数第2位の桁数を指定できるようになりました。
Time.zone.now.xmlschema(6) # => "2009-01-16T13:00:06.13653Z"
json.orgサイトで仕様を調べると、JSON構造体のキーはすべて文字列でなければならず、二重引用符で囲まなければならないことがわかります。Rails 2.3からは、数値キーについても適切に扱うようになりました。
Enumerable#none?
で、与えられたブロックにマッチする要素がないことをチェックできます。:allow_nil
オプションで、ターゲットオブジェクトが nil のときに例外を発生させずにnil
を返すようになりました。ActiveSupport::OrderedHash
がeach_key
と each_value
を実装しました。ActiveSupport::MessageEncryptor
は(cookieのような)信頼できない場所に保存する情報を暗号化する簡単な方法を提供します。from_xml
がXmlSimple に依存しなくなりました。その代わりに、Railsは必要な機能だけを備えた、独自のXmlMini実装を含むようになりました。これにより、RailsはこれまでバンドルされていたXmlSimpleのコピーから解放されました。String#parameterize
にオプションの区切り文字を渡せるようになりました。例: "Quick Brown Fox".parameterize('_') => "quick_brown_fox"
.number_to_phone
に7桁の電話番号を渡せるようになりました。ActiveSupport::Json.decode
が u0000
形式のエスケープシーケンスを処理するようになりました。上記のRackの変更に加え、Railties(Railsのコアコード)には、Rails Metal、アプリケーションテンプレート、Quiet Backtraceなど、多くの重要な変更が加えられています。
Rails Metalは、Railsアプリケーションの内部に超高速なエンドポイントを提供する新しいメカニズムです。MetalクラスはルーティングとAction Controllerをバイパスして、素の速度を提供します(もちろん、Action Controllerにあるすべてのものが使えなくなりますが)。これは、Railsを「ミドルウェアスタックを公開したRackアプリケーション」にするための最近の基礎作業の上に構築されています。Metalエンドポイントはアプリケーションやプラグインから読み込めます。
Rails 2.3には、Jeremy McAnallyによるrgアプリケーションジェネレータが組み込まれています。つまり、Railsにテンプレートベースのアプリケーション生成機能が組み込まれたということです。(他の多くのユースケースの中から)すべてのアプリケーションに含めたいプラグインのセットがある場合、テンプレートを一度セットアップしておけば、rails
コマンドを実行するときにそれらが常に適用されるようになります。また、既存のアプリケーションにテンプレートを適用するrakeタスクも用意されています。
$ rake rails:template LOCATION=~/template.rb
上を実行すると、プロジェクトにすでに含まれているコードの上に、テンプレートによる変更を配置します。
thoughtbotの Quiet Backtrace プラグインはTest::Unit
のバックトレースから選択的に行を削除できますが、Rails 2.3ではそれをベースにした ActiveSupport::BacktraceCleaner
と Rails::BacktraceCleaner
をコアに実装しています。これは、フィルタ(バックトレース行を正規表現で置換する)とサイレンサー(バックトレース行を完全に削除する)の両方をサポートします。Railsは新しいアプリケーションで最も一般的なノイズを取り除くためにサイレンサーを自動的に追加し、フィルタに追加するものを保存できるconfig/backtrace_silencers.rb
ファイルを生成します。この機能により、バックトレース中の任意のgemの出力もpretty printされるようになります。
Railsの一部(とその依存関係)が実際に必要なときだけメモリに読み込まれるようにするために、かなりの作業が行われました。コアフレームワークであるActive Support、Active Record、Action Controller、Action Mailer、Action Viewは、それぞれのクラスをautoload
で遅延読み込みするようになりました。この作業によりメモリフットプリントが抑えられ、Rails全体のパフォーマンスが向上するはずです。
また、起動時にコアライブラリをオートロードするかどうかを(新しい preload_frameworks
オプションで)指定できます。デフォルトの false
ではRailsが少しずつオートロードされますが、一度にすべてを取り込む必要が生じることもあります(PassengerとJRubyは、Railsのすべてを一括で読み込むことを希望しています)。
様々な rake gem
タスクの内部が、多くのケースでうまく動くよう大幅に改訂されました。gem システムは開発時の依存関係と実行時の依存関係の違いを認識するようになり、unpackingがより堅牢になり、gem の状態問い合わせで返される情報が改善され、スクラッチでアプリを開発するときに依存関係で「卵が先かニワトリが先か」問題を起こしにくくなりました。また、JRubyでgemコマンドを使うときや、すでにベンダリングされているgemの外部コピーを持ち込もうとする依存関係についても修正されています。
Test::Unit::TestCase
から ActiveSupport::TestCase
に変更され、RailsコアのテストでMochaが必須になりました。environment.rb
ファイルが整理されました。Rails.root
が Pathname
オブジェクトを返すようになりました。つまり、 File.join
を使っている 既存のコードをクリーンアップしてjoin
メソッドを直接使えるようになりました。rails
コマンドを実行するときに --with-dispatchers
を追加すればまだ取得できますし、後から rake rails:update:generate_dispatchers
で追加することも可能です)。script/server
に、特定のパスからRailsアプリケーションをマウントする --path
引数を渡せるようになりました。rake gems:install
が実行できないといった「卵が先かニワトリが先か」問題の多くを解決するはずです。今回のリリースで、いくつかの古いコードが非推奨化されました。
render_component
が "deprecated" から "nonexistent" に変更されました。それでも必要な場合は、render_component pluginをインストールするとよいでしょう。script/performance/request
スクリプトは現在Railsのコアから削除されました。結合テストでこのスクリプトを用いてパフォーマンスをチェックしている方は、別の新しい方法を学ぶ必要があります。新しいrequest_profilerプラグインをインストールすれば、まったく同じ機能を復元できます。ActionController::Base#session_enabled?
は、セッションが遅延読み込みされるようになったため非推奨化されました。protect_from_forgery
の :digest
と :secret
オプションは非推奨化されました(無効なオプションです)。response.headers["Status"]
と headers["Status"]
は何も返さなくなりました。Rack は戻り値のヘッダに "Status" を使うことを許可していません。しかし、 status
ヘルパーや status_message
ヘルパーは利用可能です。response.headers["cookie"]
と headers["cookie"]
は CGI cookieを一切返さなくなりました。生のcookieヘッダを見るために headers["Set-Cookie"]
を検査したり、クライアントに送信されたcookieのハッシュを取得するために cookies
ヘルパーを利用することは可能です。formatted_polymorphic_url
は非推奨化されました。代わりに polymorphic_url
と :format
をお使いください。ActionController::Response#set_cookie
の :http_only
オプション名は :httponly
に変更されました。to_sentence
の :connector
オプションと :skip_last_comma
オプションは、 :words_connector
, :two_words_connector
, :last_word_connector
オプションに置き換わりました。file_field
コントロールが空になっているマルチパートフォームを送信すると、以前は空文字列がコントローラに送信されていましたが、現在はnilを送信するようになりました。これは、Rack のマルチパートパーサーと Rails の古いパーサーとの違いに起因します。リリースノート編集担当:Mike Gunderloy。このRails 2.3リリースノートは、Rails 2.3 RC2を元に編集されています。
Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。
原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨
本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。
Railsガイド運営チーム (@RailsGuidesJP)
Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。