Ruby on Rails Guides: Ruby on Rails 3.1 Release Notesを自分用に和訳してみた

英語の勉強兼、自分への備忘録としてRails 3.1 のリリースノートを和訳してみました。
ところどころ、良く分かってないので直訳になってたり、微妙に不可解な日本語になってたりする箇所があります。
ご容赦ください。
間違いに気付いた方はご指摘していただけるとありがたいです。

1 Upgrading to Rails 3.1 (サポート環境以外は省略)

Rails3.1はRuby 1.8.7以上が必要。
1.8.7-p248,p249はマーシャルのバグでRailsがクラッシュする。
1.9.1はオススメしないので、1.9系を使う時は1.9.2を使ってね。

2 Creating a Rails 3.1 application

(省略)

3 Rails Architectural Changes

3.1 Assets Pipeline

Rails3.1での大きな変更はAssets Pipelineです。
これはCSSJavaScriptのコードを生成して、いい感じに統合してくれます。
プラグインやエンジンの中で利用するものも含みます。

3.2 HTTP Streaming

HTTP StreamingはRails3.1のもう一つの新機能です。
これはブラウザが、サーバーがまだレスポンスを生成している途中でも、
CSSとかJavaScriptのファイルをダウンロードできるようにしてくれます。
この機能を使うには、Ruby 1.9.2と対応したWebサーバが必要です。
一般的な組み合わせとしては、nginxとunicorn等。

3.3 Default JS library is now jQuery

jQeuryがデフォルトで使われるJavaScriptライブラリになりました。
もしPrototypeを使いたい場合は、以下のコマンドで生成できます。

$ rails new myapp -j prototype
3.4 Identity Map

Rails 3.1ではActiveRecordにIdentity Mapという機能が追加されました。
Identity Mapは以前に作られたレコードとそれに関連付けられたオブジェクトを保持しておき、
再度アクセスされた時にそのオブジェクトそのものを返す機能です。
Identyty Mapはリクエストごとに動作し、リクエストが完了すると保持しているオブジェクトはフラッシュされます。


Rails 3.1ではIdentity Mapはデフォルトではオフになっています。

4 Railties

  • jQueryがデフォルトに。
  • アプケーションのジェネレーターは、-jオプションの引数として、決まった文字列を取る必要は無い。もし"foo"という文字列が渡された場合は、"foo-rails"というgem名がGemfileに追加される。そしてJavaScriptマニフェストファイルに "foo"と"foo_ujs"をrequireするように記述される。今のところ、asset pipeline経由でこのあたりのファイルを提供してくれる"prototype-rails"と"jquery-rails"がある。
  • アプリケーション、あるいはプラグインの生成は、--skip-gemfile か --skip-bundle オプションを付けてない時には、bundle installを実行する。
  • コントローラーとリソースのジェネレーターは、自動的にasset用のスタブを生成する。これらのスタブは、もし利用可能であればCoffeeScriptとSassを使うようになっている。
  • Scaffoldとアプリケーションのジェネレーターは、Ruby 1.9で実行された時には、Ruby 1.9形式のハッシュ記述を利用する。古い形式のハッシュ記述を利用したい場合は、 --old-style-hash オプションを渡すことで利用できる。
  • Scaffold controllerジェネレーターは、XMLに代わってJSON形式でformatのレスポンスブロックを生成する。
  • Active Recordは直接に標準出力へログ出力する。そしてコンソール内ではインラインで表示される。
  • config.force_ssl という設定が追加された。

この設定は Rack::SSL ミドルウェアを読み込み、強制的に全てのリクエストをHTTPSプロトコルで処理する。

  • rails plugin new というコマンドが追加された。このコマンドはgemspec, テストコード, テストのためのダミーアプリケーションを含むプラグインの雛形を生成する。
  • Rack::Etag, Rack::ConditionalGet がデフォルトのミドルウェアスタックに追加された。
  • エンジンはメジャーアップデートされた。どんなパスにもマウントできるようになったし、assetsの有効化、ジェネレーターの実行、等々

5 Action Pack

5.1 Action Controller
  • CSRFトークン認証が検証できない時は、warningを出すようになった。
  • force_ssl をコントローラー内で指定することで、特定のコントローラーからのデータ転送をHTTPSで行う。:onlyや:exceptを使って特定のアクションに制限することも可能。
  • 出力されるとまずいようなクエリパラメーターを config.filter_parameters で指定しておくことで、リクエストパスのログ出力にフィルターをかけることができる。
  • ActionController::ParamsWrapper クラスが追加された。このクラスは、JSONリクエストがデフォルトで有効にするために、ネストされたハッシュのなかにパラメーターをラップする。この動作は、 config/initializers/wrap_parameters.rb でカスタマイズできる。
  • config.action_controller.include_all_helpers の設定が追加された。デフォルトではActionController::Base内で、 helper :all を指定すると、全てのヘルパークラスがデフォルトでインクルードされる。include_all_helpers を false に設定すると、コントローラーに関係するヘルパーしかインクルードされなくなる。
  • url_for と名前付きURLヘルパーは、:subdomainと:domainというシンボルをオプションとして受け取れるようになった。
  • ActionController::Base.http_basic_authenticate_with (単純なベーシック認証を実現する) が単純なクラスメソッドとして呼び出せるようになった。

以前は、こう。

class PostsController < ApplicationController
  USER_NAME, PASSWORD = "dhh", "secret"
 
  before_filter :authenticate, :except => [ :index ]
 
  def index
    render :text => "Everyone can see me!"
  end
 
  def edit
    render :text => "I'm only accessible if you know the password"
  end
 
  private
    def authenticate
      authenticate_or_request_with_http_basic do |user_name, password|
        user_name == USER_NAME && password == PASSWORD
      end
    end
end

これがこう書ける。

class PostsController < ApplicationController
  http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index
 
  def index
    render :text => "Everyone can see me!"
  end
 
  def edit
    render :text => "I'm only accessible if you know the password"
  end
end
  • ストリーミングのサポートが追加された。有効にしたい時は以下のように書く。
class PostsController < ActionController::Base
  stream
end


2011/9/4 追記: 上記の記述は既に非推奨になっていました。現在の正しい記述は以下の通り。

class PostsController < ActionController::Base
  def index
    @posts = Post.all
    render :stream => true
  end
end


:onlyや:exceptを使って、特定のアクションに制限することも出来る。
より細かい情報はActionController::Streamingを参照。

5.2 Action Dispatch
  • config.action_dispatch.x_sendfile_header はデフォルトでnilが設定されるようになった。config/environments/production.rb でも特定の値は設定されていない。これは、X-SendFile-Typeヘッダをスルーする設定をサーバーに許す。
  • ActionDispatch::MiddlewareStack は継承ではなくオブジェクト内包を利用するようになったため、もはや配列の一種では無くなった。
  • ブラウザの送信する accept headers を無視するために、ActionDispatch::Request.ignore_accept_header が追加された。
  • Rack::Cache がデフォルトのスタックに追加された。
  • etagへの応答性は、ActionDispatch::Response からミドルウェアスタックに移った。
  • Rack::Session の保存用APIは、Rubyの世界とより良い互換性を持つようになった。これは以下の点で、後方互換性が失くなっている。Racl::Session#get_session が4つの引数を持つこと、#destroyの変わりに#destroy_sessionが必要であること。*1
  • テンプレートのルックアップは、継承チェインでさらに良くなった。*2
5.3 Action View
  • CSRFトークンを取り除いたり、自前で処理するための選択肢として、form_tag ヘルパーに :authenticity_token オプションが追加された。
  • SafeBuffer をインプレイスで変更するのは禁止された。(In place SafeBuffer mutation is prohibited in Rails 3.1.) *3
  • HTML5の button_tag ヘルパーが追加された
  • file_field ヘルパーは自動的に :multipart => true をフォームタグに追加する。
  • HTML5の data-* 記法を生成するために、tag ヘルパーに便利なイディオムが追加された。:dataにハッシュオブジェクトを渡すことで利用する。
tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)})
# => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />

キーはダッシュ化され、バリューは文字列とシンボル以外はJSONエンコードされる。

  • 古いテンプレートハンドラーAPIは廃止された。そして新しいAPIに対応するためには、テンプレートハンドラーは単にcallに応答できればよい。
  • rhtmlとrxmlはついにハンドラーから消えた。
  • テンプレートがキャッシュされるべきかそうでないかを決められるように、config.action_view.cache_template_loading は復活した。
  • submit ヘルパーは、"object_name_id"というidを生成しない
  • form_for ヘルパーは、:html ハッシュを経由せずに、直接 :method オプションを指定できるようになった。
form_for(@post, remote: true, method: :delete)
  • JavaScriptHelper#j() が JavascriptHelper#escape_javascript() へのエイリアスとして追加された。これはJSON gemで追加される Object#j() に優先する。
  • auto_link はRailsから分離して、rails_autolink_gem によって提供されるようになった。

6 Active Record

  • クラスメソッドに pluralize_table_names が追加された。個々のモデルで、テーブル名を複数形にするか単数形にするか制御できる。以前は、ActiveRecord::Base.pluralize_table_namesを通して全てのモデルに対してしか設定できなかった。
class User < ActiveRecord::Base
  self.pluralize_table_names = false
end
  • 1:1関連に対して、属性を設定するためのブロックが追加された。このブロックは、インスタンスが初期化された後に呼び出される。
class User < ActiveRecord::Base
  has_one :account
end
 
user.build_account{ |a| a.credit_limit => 100.0 }
  • 属性名のリストを返すための ActiveRecod::Base.attribute_names メソッドが追加された。これはモデルが抽象クラスでテーブルを持たない時、空のリストを返す。
  • CSVフィクスチャはRails 3.2.0で削除されるだろう。
  • ActiveRecord#new, #create, #update_attributesは、オプションとして二つめのハッシュを取るようになった。これは属性をアサインする際にロールを指定できるようにする。
class Post < ActiveRecord::Base
  attr_accessible :title
  attr_accessible :title, :published_at, :as => :admin
end
 
Post.new(params[:post], :as => :admin)
  • default_scope は遅延評価のために、コードブロック、lambda、その他 call を受け付けるオブジェクトを引数に取るようになった。
  • デフォルトのスコープ設定は、可能な限り後で評価される。これは暗黙的にデフォルトのスコープを含むスコープが作成された時、Model.unscoped 経由でスコープを除去できなくなることを避けるためだ。
  • ConnectionManagement ミドルウェアは rack bodyがフラッシュされた後に、コネクションプールをクリーンアップするように変更された。
  • update_column メソッドが追加された。これはバリデーションとコールバックをスキップして、属性を更新するメソッドだ。例えば、 updated_at カラムを修正する等、コールバックを動かしたくないことがはっきりしている場合以外は、このメソッドは非推奨だ。update_attributeを使うように。また、新規レコードに対しては利用するべきではない。
  • :through オプション付きの関連は、元となるモデルがその他の、:throgh 付き関連や、has_and_belongs_to_many 関連を持っていても利用可能になった。
  • 現在のデータベース接続設定は、ActiveRecord::Base.connection_config を経由してアクセス出来るようになった。
  • limits と offsets は両方を指定しないと、COUNT クエリから除去される。
People.limit(1).count           # => 'SELECT COUNT(*) FROM people'
People.offset(1).count          # => 'SELECT COUNT(*) FROM people'
People.limit(1).offset(1).count # => 'SELECT COUNT(*) FROM people LIMIT 1 OFFSET 1'
  • ActiveRecord::Associations::AssociationProxy は分割された。関連上での操作を担当する Association クラスと、集合型の関連へのプロキシとなる CollectionProxy クラスが存在する。これは、名前空間汚染の回避や、分割の養成、更なるリファクタリングのためだ。
  • 1:1の関連は、プロキシオブジェクトを返さなくなった。戻り値は、単純に関連したレコードのオブジェクトか nil になる。これは、ドキュメント化されていないメソッド呼び出しが利用できなくなったことを意味する。例えば、 bob.create_mother の代わりに bob.mother.create を使うような。
  • has_many :through 関連で :dependent オプションがサポートされた。歴史的経緯と実践的な理由で、通常の has_many 関連は :nullify がデフォルトであるのに、 :delete_all がデフォルトで採用されている。また、このオプションは belongs_to によって関連元が参照出来る時にしか機能しない。それ以外の場合は、直接関連を修正するのが良い。
  • has_and_belongs_to_many と has_many :through への association.destroy の振舞いが変更された。'destroy'と'delete'はリンクの除去を意味し、必ずしも関連レコードの除去を意味しない。
  • 以前の has_and_belongs_to_many.destroy(*records) はrecords自身を削除していた。結合テーブル上のレコードは削除されなかった。3.1では、結合テーブル上でレコードが削除されるようになった。
  • 以前の has_many_through.destroy(*records) はrecords自身を削除していた。結合テーブル上のレコードは削除されなかった。3.1では、結合テーブル上でのみレコードが削除されるようになった。
  • change_table に :bulk => true オプションが追加された。テーブルへの複数の変更を一つの ALTER ステートメントにまとめる。
change_table(:users, :bulk => true) do |t|
  t.string :company_name
  t.change :birthdate, :datetime
end
  • has_and_belongs_to_many の結合テーブル上の属性へのアクセスはサポートされなくなった。has_many :throughを使う必要がある。
  • has_one と belongs_to の関連のために create_association! メソッドが追加された。
class MyMigration < ActiveRecord::Migration
  def change
    create_table(:horses) do
      t.column :content, :text
      t.column :remind_at, :datetime
    end
  end
end
  • 自動的に逆行できない場合は、今までどおり、 up と down に定義する。もし change に定義していて逆行できない場合は、逆方向へのマイグレーション実施時に、 IrreversibleMigration 例外が発生する。
class FooMigration < ActiveRecord::Migration
  def up # Not self.up
    ...
  end
end
  • マイグレーション用のファイルは、ジェネレーターから作成された時は、change メソッドを使った、逆行可能な記述を利用する。
  • 関連のSQL検索条件を設定するために文字列を渡すことはサポートされない。代わりに、proc を使うのがよい。
has_many :things, :conditions => 'foo = #{bar}'          # before
has_many :things, :conditions => proc { "foo = #{bar}" } # after

procの中で、self は関連の所有者のオブジェクトになる。

procの中で、一般的な条件指定の記法を使うこともできる。

has_many :things, :conditions => proc { ["foo = ?", bar] }
  • 以前は、has_and_belongs_to_many 関連で、:insert_sql, :delete_sqlに対して、'record'を呼ぶことで、挿入もしくは削除されたレコードを参照することが出来たが、3.1ではprocに対する引数として渡すことで呼び出すようになった。
  • ActiveRecord::Base#has_secure_password (via ActiveModel::SecurePassword) メソッドが追加された。これは、BCrypt による暗号化とソルトを使って、パスワードを格納する。
# Schema: User(name:string, password_digest:string, password_salt:string)
class User < ActiveRecord::Base
  has_secure_password
end
  • モデルが生成される時、belongs_to か references カラムのために、デフォルトで add_index が追加される。
  • オブジェクトに対して、belongs_to のIDを設定すると、そのオブジェクトに対する参照は更新される。
  • ActiveRecord::Base#dup, #clone は、Rubydup と clone に近い動きをするように変更された。
  • #clone はレコードに対する、浅いコピーを行う。状態のfreezeも含んだ複製を行う。コールバックは呼ばれない。
  • #dup はレコードそのものを複製する。状態のfreezeはコピーされない。そして、全ての関連はクリアされる。複製されたレコードは new_record? に対してtrueを返し、id フィールドは空で、保存可能な状態になる。
  • クエリキャッシュは、プリペアードステートメントでも動作するようになった。アプリケーションへの変更は不要。

7 Active Model

  • attr_accesible がロールを指定するための :as オプションを受け取るようになった。
  • InclusionValidator, ExclusionValidator, FormatValidatorは、proc, lambda, その他 call に応答できるオブジェクトをオプションとして受け取るようになった。このオプションは、今のレコードを引数として呼び出され、InclusionValidator と ExclusionValidatorの include? に応答するためのオブジェクトを返す、または、FormatValidatorのための正規表現オブジェクトを返す。*4
  • ActiveModel::SecurePassword が追加された。Bcryptによる暗号化を行う。
  • モデルに対するオブザーバを個別にオン・オフ出来るようになった。
  • I18nネームスペースへの代替検索はサポートされなくなった。

8 Active Resource

  • デフォルトのフォーマットがJSONに変更された。もしXMLを使い続けたいなら、 self.format = :xml をクラス内に記述する。
class User < ActiveResource::Base
  self.format = :xml
end

9 Active Support

  • ActiveSupport::Dependencies は、load_missing_constant内で存在している定数を見つけた時、NameError 例外を出すようになった。
  • 追加されたKernel#quietly メソッドは、STDOUTとSTDERRを黙らせる。
  • String オブジェクトを StringInquirer オブジェクトに変換するために String#inquiry メソッドが追加された。
"production".inquiry.production? # => true
  • オブジェクトが他のオブジェクトにインクルードされているかを調べるための、Object#in? メソッドが追加された。
  • LocalCache は実際のミドルウェアクラスになったので、もはや匿名クラスではない。
  • 再読み込み可能なクラスへの参照を保持しておくため、ActiveSupport::Dependencies::ClassCache クラスが導入された。
  • Range#cover? は Ruby 1.8において、Range#include? へのエイリアスとしてバックポートされた。
  • Date/DateTime/Time クラスに weeks_ago, prev_week が追加された。
  • ActiveSupport::Dependencies.remove_unloadable_constants! へのコールバックとして、before_remove_const が追加された。
  • ActiveSupport::SecureRandom は、Rubyの標準ライブラリのSecureRandomの方が望ましいため、廃止された。


ああ、疲れた・・・。
これ需要あんのかなあ?

*1:訳注: このあたり、ちゃんと分かってない

*2:訳注: 訳せてないw

*3:訳注: 意味が分からなかった

*4:ここも良く分かってない