More at rubyonrails.org: More Ruby on Rails

Ruby on Railsアップグレードガイド

本ガイドでは、Ruby on Railsアプリケーションで使用されているRuby on Railsを新しいバージョンにアップグレードする際に従う必要のある手順を示します。これらの手順は、各バージョンのリリースガイドにも記載されています。

1 一般的なアドバイス

言うまでもないことですが、既存のアプリケーションをアップグレードする際には、何のためにアップグレードするのかをはっきりさせておく必要があります。新しいバージョンのうち必要な機能が何であるのか、既存のコードのサポートがどのぐらい困難になるのか、アップグレードに必要な時間とスキルはどのぐらいになるのか、など、少し考えるだけでいくつもの要素を調整しなければなりません。

1.1 テスティングのカバレッジ

アップグレード後にアプリケーションが正常に動作していることを確認する方法としては、良いテストカバレッジをアップグレード前に準備しておくのが最善です。アプリケーションを一気に検査する自動テストがないと、変更点をすべて手動で確認しなければならず膨大な時間がかかってしまいます。Railsのようなアプリケーションの場合、これはアプリケーションのあらゆる機能を一つ残らず確認しなければならないということです。アップグレードの実施は、テストカバレッジをきちんと準備してから行なうよう、お願いいたします。

1.2 Rubyのバージョン

Railsは、そのバージョンがリリースされた時点で最新のバージョンのRubyに依存しています。

  • Rails 3以上では、Ruby 1.8.7以降が必須です。これより古いRubyのサポートは公式に停止しています。できるだけ早くアップグレードをお願いします。
  • Rails 3.2.xはRuby 1.8.7の最終ブランチです。
  • Rails 4ではRuby 2.0が推奨されます。Ruby 1.9.3以上が必須です。

ヒント: Ruby 1.8.7 p248およびp249にはRailsをクラッシュさせるマーシャリングバグがあります。Ruby Enterprise Editionでは1.8.7-2010.02以降このバグは修正されています。Ruby 1.9系を使用する場合、Ruby 1.9.1はあからさまなセグメンテーション違反が発生するため使用できません。1.9.3をご使用ください。

2 Rails 4.0からRails 4.1へのアップグレード

メモ: このセクションはまだ完成していません。

2.1 リモート <script> タグにCSRF保護を実施

これを行わないと、「なぜかテストがとおらない...orz」ということになりかねません。

JavaScriptレスポンスを伴うGETリクエストもクロスサイトリクエストフォージェリ (CSRF) 保護の対象となりました。この保護によって、第三者のサイトが重要なデータの奪取のために自分のサイトのJavaScript URLを参照して実行しようとすることを防止します。

つまり、以下を使用する機能テストと結合テストは

get :index, format: :js

CSRF保護をトリガーするようになります。以下のように書き換え、

xhr :get, :index, format: :js

XmlHttpRequestを明示的にテストしてください。

本当にJavaScriptをリモートの<script>タグから読み込むのであれば、そのアクションではCSRF保護をスキップしてください。

2.2 Spring

アプリケーションのプリローダーとしてSpringを使用する場合は、以下を行う必要があります。

  1. gem 'spring', group: :developmentGemfileに追加する
  2. bundle installを実行してSpringをインストールする
  3. bundle exec spring binstub --allを実行してbinstubをSpring化する

メモ: ユーザーが定義したRakeタスクはデフォルトでdevelopment環境で動作するようになります。これらのRakeタスクを他の環境でも実行したい場合はSpring READMEを参考にしてください。

2.3 config/secrets.yml

新しいsecrets.ymlに秘密鍵を保存したい場合は以下のようにします。

  1. secrets.ymlファイルをconfigフォルダに作成し、以下の内容を追加します。

    development:
      secret_key_base:
    
    test:
      secret_key_base:
    
    production:
      secret_key_base:
    
    
  2. 既存のsecret_key_basesecret_token.rbイニシャライザからsecrets.ymlproductionセクションにコピーします。

  3. secret_token.rbイニシャライザを削除します

  4. rake secretを実行し、developmentセクションtestセクションに新しい鍵を生成します。

  5. サーバーを再起動します。

2.4 テストヘルパーの変更

テストヘルパーにActiveRecord::Migration.check_pending!の呼び出しがある場合、これを削除することができます。このチェックはrequire 'test_help'の際に自動的に行われるようになりました。この呼び出しを削除しなくても悪影響が生じることはありません。

2.5 Cookiesシリアライザ

Rails 4.1より前に作成されたアプリケーションでは、Marshalを使用してcookie値を署名済みまたは暗号化したcookies jarにシリアライズしていました。アプリケーションで新しいJSONベースのフォーマットを使用したい場合、以下のような内容を持つイニシャライザファイルを追加できます。

  Rails.application.config.cookies_serializer :hybrid

これにより、Marshalでシリアライズされた既存のcookiesを、新しいJSONベースのフォーマットに透過的に移行できます。

2.6 Flash構造の変更

Flashメッセージのキーが文字列に正規化 されました。シンボルまたは文字列のどちらでもアクセスできます。Flashのキーを取り出すと常に文字列になります。

flash["string"] = "a string"
flash[:symbol] = "a symbol"

# Rails < 4.1
flash.keys # => ["string", :symbol]

# Rails >= 4.1
flash.keys # => ["string", "symbol"]

Flashメッセージのキーを文字列と比較するようにしてください。

2.7 JSONの扱いの変更点

Rails 4.1ではJSONの扱いが大きく変更された点が4つあります。

2.7.1 MultiJSONの廃止

MultiJSONはその役目を終えて end-of-life Railsから削除されました。

アプリケーションがMultiJSONに直接依存している場合、以下のような対応方法があります。

  1. 'multi_json'をGemfileに追加する。ただしこのGemは将来使えなくなるかもしれません。

  2. obj.to_jsonJSON.parse(str)を使用してMultiJSONから乗り換える

警告: MultiJson.dumpMultiJson.loadをそれぞれJSON.dumpJSON.loadに単純に置き換えては「いけません」。これらのJSON gem are meant for serializing and deserializing arbitrary Ruby objects and are generally [unsafe]APIは任意のRubyオブジェクトをシリアライズおよびデシリアライズするためのものであり、一般に安全ではありません

2.7.2 JSON gemの互換性

これまでのRailsは、JSON gemとの互換性に何らかの問題が生じていました。Railsアプリケーション内のJSON.generateJSON.dumpではときたまエラーが生じることがありました。

Rails 4.1では、Rails自身のエンコーダをJSON gemから切り離すことでこれらの問題が修正されました。JSON gem APIは今後正常に動作しますが、その代わりJSON gem APIからRails特有の機能にアクセスすることはできなくなります。例:

class FooBar
  def as_json(options = nil)
    { foo: 'bar' }
end
end

>> FooBar.new.to_json # => "{\"foo\":\"bar\"}"
>> JSON.generate(FooBar.new, quirks_mode: true) # => "\"#<FooBar:0x007fa80a481610>\""

2.7.3 新しいJSONエンコーダ

Rails 4.1のJSONエンコーダは、JSON gemを使用するように書き直されました。大半のアプリケーションではこの変更は透過的になる(=影響しない)はずです。ただし、エンコーダが書き直された際に以下の機能がエンコーダから削除されました。

  1. データ構造の循環検出
  2. encode_jsonフックのサポート
  3. BigDecimalオブジェクトを文字ではなく数字としてエンコードするオプション

アプリケーションがこれらの機能に依存している場合は、activesupport-json_encoder gemをGemfileに追加することで以前の状態に戻すことができます。

2.8 インラインコールバックブロックでreturnの使用法

以前のRailsでは、インラインコールバックブロックで以下のようにreturnを使用することができました。

class ReadOnlyModel < ActiveRecord::Base
  before_save { return false } # 良くない
end

この動作は決して意図されたものではありません。ActiveSupport::Callbacksが書き直され、上のような動作はRails 4.1では許されなくなりました。インラインコールバックブロックでreturn文を書くと、コールバック実行時にLocalJumpErrorが発生するようになりました。

インラインコールバックブロックでreturnを使用している場合、以下のようにリファクタリングすることで、返された値として評価されるようになります。

class ReadOnlyModel < ActiveRecord::Base
  before_save { false } # 良い
end

returnを使用したいのであれば、明示的にメソッドを定義することが推奨されます。

class ReadOnlyModel < ActiveRecord::Base
  before_save :before_save_callback # 良い

  private
    def before_save_callback
      return false
    end
end

この変更は、Railsでコールバックを使用している多くの箇所に適用されます。これにはActive RecordとActive ModelのコールバックやAction Controllerのフィルタ(before_action など)も含まれます。

詳細についてはこのpull requestを参照してください。

2.9 Active Recordフィクスチャで定義されたメソッド

Rails 4.1では、各フィクスチャのERBは独立したコンテキストで評価されます。このため、あるフィクスチャで定義されたヘルパーメソッドは他のフィクスチャでは利用できません。

ヘルパーメソッドを複数のフィクスチャで使用するには、4.1で新しく導入されたActiveRecord::FixtureSet.context_class (test_helper.rb) に含まれるモジュールで定義する必要があります。

class FixtureFileHelpers
  def file_sha(path)
    Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
end
end
ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers

2.10 I18nオプションでavailable_localesリストの使用が強制される

Rails 4.1からI18nオプションenforce_available_locales がデフォルトでtrueになりました。この設定では、I18nに渡されるすべてのロケールはavailable_localesリストで宣言されていないと使用できなくなります。

この機能をオフにしてI18nですべての種類のロケールオプションを使用できるようにするには、以下のように変更します。

config.i18n.enforce_available_locales = false

available_localesの強制はセキュリティのために行われていることにご注意ください。つまり、アプリケーションが把握していないロケールを持つユーザー入力が、ロケール情報として使用されることのないようにするためのものです。従って、やむを得ない理由がない限りこのオプションはfalseにしないでください。

2.11 リレーションに対するミューテーターメソッド呼び出し

Relationには#map!#delete_ifなどのミューテーターメソッド (mutator method) が含まれなくなりました。これらのメソッドを使用したい場合は#to_aを呼び出してArrayに変更してからにしてください。

この変更は、Relationに対して直接ミューテーターメソッドを呼び出すことによる奇妙なバグや混乱を防止するために行われました。

# 以前のミューテーター呼び出し方法
Author.where(name: 'Hank Moody').compact!

# 今後のミューテーター呼び出し方法
authors = Author.where(name: 'Hank Moody').to_a
authors.compact!

2.12 デフォルトスコープの変更

デフォルトのスコープは、条件を連鎖した場合にオーバーライドされなくなりました。

以前のバージョンでは、モデルでdefault_scopeを定義すると、同じフィールドで連鎖した条件によってオーバーライドされました。現在は、他のスコープと同様、マージされるようになりました。

変更前:

class User < ActiveRecord::Base
  default_scope { where state: 'pending' }
  scope :active, -> { where state: 'active' }
  scope :inactive, -> { where state: 'inactive' }
end

User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'

User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'

User.where(state: 'inactive')
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'

変更後:

class User < ActiveRecord::Base
  default_scope { where state: 'pending' }
  scope :active, -> { where state: 'active' }
  scope :inactive, -> { where state: 'inactive' }
end

User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'

User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'

User.where(state: 'inactive')
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'

以前と同じ動作に戻したい場合は、unscopedunscoperewhere、またはexceptを使用してdefault_scopeの条件を明示的に除外する必要があります。

class User < ActiveRecord::Base
  default_scope { where state: 'pending' }
  scope :active, -> { unscope(where: :state).where(state: 'active') }
  scope :inactive, -> { rewhere state: 'inactive' }
end

User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'

User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'

User.inactive
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'

2.13 文字列からのコンテンツ描出

Rails 4.1のrender:plain:html:bodyオプションが導入されました。以下のようにコンテンツタイプを指定できるため、文字列ベースのコンテンツ表示にはこれらのオプションの使用が推奨されます。

  • render :plainを実行するとcontent typeはtext/plainに設定される
  • render :htmlを実行するとcontent typeはtext/htmlに設定される
  • render :bodyを実行した場合、content typeヘッダーは「設定されない」

セキュリティ上の観点から、レスポンスのbodyにマークアップを含めない場合にはrender :plainを使用すべきです。これによって多くのブラウザが安全でないコンテンツをエスケープできるからです。

今後のバージョンでは、render :textは非推奨にされる予定です。今のうちに、正しい:plain::html:bodyオプションに切り替えてください。render :textを使用するとtext/htmlで送信されるため、セキュリティ上のリスクが生じる可能性があります。

3 Rails 3.2からRails 4.0へのアップグレード

Railsアプリケーションのバージョンが3.2より前の場合、まず3.2へのアップグレードを完了してからRails 4.0へのアップグレードにとりかかってください。

以下の変更は、アプリケーションをRails 4.0にアップグレードするためのものです。

3.1 HTTP PATCH

Rails 4では、config/routes.rbでRESTfulなリソースが宣言されたときに、更新用の主要なHTTP verbとしてPATCHが使用されるようになりました。updateアクションは従来通り使用でき、PUTリクエストは今後もupdateアクションにルーティングされます。 標準的なRESTfulのみを使用しているのであれば、これに関する変更は不要です。

resources :users

<%= form_for @user do |f| %>

class UsersController < ApplicationController
  def update
    # 変更不要:PATCHが望ましいがPUTも使用できる
end
end

ただし、form_forを使用してリソースを更新しており、PUT HTTPメソッドを使用するカスタムルーティングと連動しているのであれば、変更が必要です。

resources :users, do
  put :update_name, on: :member
end

<%= form_for [ :update_name, @user ] do |f| %>

class UsersController < ApplicationController
  def update_name
    # 変更が必要: form_forは、存在しないPATCHルートを探そうとする
end
end

このアクションがパブリックなAPIで使用されておらず、HTTPメソッドを自由に変更できるのであれば、ルーティングを更新してpatchputの代りに使用できます。

Rails 4でPUTリクエストを/users/:idに送信すると、従来通りupdateにルーティングされます。このため、実際のPUTリクエストを受け取るAPIは今後も動作します。 この場合、PATCHリクエストも/users/:id経由でupdateアクションにルーティングされます。

resources :users do
  patch :update_name, on: :member
end

このアクションがパブリックなAPIで使用されており、HTTPメソッドを自由に変更できないのであれば、フォームを更新してPUTを代りに使用できます。

<%= form_for [ :update_name, @user ], method: :put do |f| %>

PATCHおよびこの変更が行われた理由についてはRailsブログの この記事 を参照してください。

3.1.1 メディアタイプに関するメモ

PATCH verbに関する追加情報 PATCHでは異なるメディアタイプを使用する必要があるJSON Patch などが該当します。RailsはJSON Patchをネイティブではサポートしませんが、サポートは簡単に追加できます。

# コントローラに以下を書く
def update
  respond_to do |format|
    format.json do
      # perform a partial update
      @post.update params[:post]
    end

    format.json_patch do
      # perform sophisticated change
    end
  end
end

# config/initializers/json_patch.rb に以下を書く
Mime::Type.register 'application/json-patch+json', :json_patch

JSON Patchは最近RFC化されたばかりなのでRubyライブラリはそれほどありません。Aaron Pattersonの hana gemが代表的ですが、最新の仕様変更をすべてサポートしているわけではありません。

3.2 Gemfile

Rails 4.0ではassetsグループがGemfileから削除されました。アップグレード時にはこの記述をGemfileから削除する必要があります。アプリケーションのconfig/application.rbファイルも以下のように更新する必要があります。

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)

3.3 vendor/plugins

Rails 4.0 では vendor/plugins 読み込みのサポートは完全に終了しました。使用するプラグインはすべてgemに展開してGemfileに追加しなければなりません。理由があってプラグインをgemにしないのであれば、プラグインをlib/my_plugin/*に移動し、適切な初期化の記述をconfig/initializers/my_plugin.rbに書いてください。

3.4 Active Record

  • 関連付けに関する若干の不整合 のため、Rails 4.0ではActive Recordからidentity mapが削除されました。この機能をアプリケーションで手動で有効にしたい場合は、今や効果のない config.active_record.identity_mapを削除する必要があるでしょう。

  • コレクション関連付けのdeleteメソッドは、FixnumString引数をレコードの他にレコードIDとしても受け付けるようになりました。これによりdestroyメソッドの動作にかなり近くなりました。以前はこのような引数を使用するとActiveRecord::AssociationTypeMismatch例外が発生しました。Rails 4.0からは、deleteメソッドを使用すると、与えられたIDにマッチするレコードを自動的に探すようになりました。

  • Rails 4.0では、カラムやテーブルの名前を変更すると、関連するインデックスも自動的にリネームされるようになりました。インデックス名を変更するためだけのマイグレーションは今後不要になりました。

  • Rails 4.0のserialized_attributesメソッドとattr_readonlyメソッドは、クラスメソッドとしてのみ使用するように変更されました。これらのメソッドをインスタンスメソッドとして使用することは非推奨となったため、行わないでください。たとえばself.serialized_attributesself.class.serialized_attributesのようにクラスメソッドとして使用してください。

  • Rails 4.0ではStrong Parametersの導入に伴い、attr_accessibleattr_protectedが廃止されました。これらを引き続き使用したい場合は、Protected Attributes gem を導入することでスムーズにアップグレードすることができます。

  • Protected Attributesを使用していないのであれば、whitelist_attributesmass_assignment_sanitizerオプションなど、このgemに関連するすべてのオプションを削除できます。

  • Rails 4.0のスコープでは、Procやlambdaなどの呼び出し可能なオブジェクトの使用が必須となりました。

  scope :active, where(active: true)

上のコードは以下のように変更する必要があります。
  scope :active, -> { where active: true }

  • ActiveRecord::FixtureSetの導入に伴い、Rails 4.0ではActiveRecord::Fixturesが非推奨となりました。

  • ActiveSupport::TestCaseの導入に伴い、Rails 4.0ではActiveRecord::TestCaseが非推奨となりました。

  • Rails 4.0では、ハッシュを使用する旧来のfinder APIが非推奨となりました。これまでfinderオプションを受け付けていたメソッドは、これらのオプションを今後受け付けなくなります。

  • 動的なメソッドは、find_by_...find_by_...!を除いて非推奨となりました。 以下のように変更してください。

    • find_all_by_... に代えて`where(...)を使用
    • find_last_by_... に代えてwhere(...).lastを使用
    • scoped_by_... に代えてwhere(...)を使用
    • find_or_initialize_by_... に代えてfind_or_initialize_by(...)を使用
    • find_or_create_by_... に代えてfind_or_create_by(...)を使用
  • 旧来のfinderが配列を返していたのに対し、where(...)はリレーションを返します。Arrayが必要な場合は, where(...).to_aを使用してください。

  • これらの同等なメソッドが実行するSQLは、従来の実装と同じではありません。

  • 旧来のfinderを再度有効にしたい場合は、activerecord-deprecated_finders gem を使用できます。

3.5 Active Resource

Rails 4.0ではActive Resourceがgem化されました。この機能が必要な場合はActive Resource gem をGemfileに追加できます。

3.6 Active Model

  • Rails 4.0ではActiveModel::Validations::ConfirmationValidatorにエラーがアタッチされる方法が変更されました。確認バリデーションが失敗したときに、attributeではなく:#{attribute}_confirmationにアタッチされるようになりました。

  • Rails 4.0のActiveModel::Serializers::JSON.include_root_in_jsonのデフォルト値がfalseに変更されました。これにより、Active Model SerializersとActive Recordオブジェクトのデフォルトの動作が同じになりました。これにより、config/initializers/wrap_parameters.rbファイルの以下のオプションをコメントアウトしたり削除したりできるようになりました。

# Disable root element in JSON by default.
# ActiveSupport.on_load(:active_record) do
#   self.include_root_in_json = false
# end

3.7 Action Pack

  • Rails 4.0からActiveSupport::KeyGeneratorが導入され、署名付きcookiesの生成と照合などに使用されるようになりました。Rails 3.xで生成された既存の署名付きcookiesは、既存のsecret_tokenはそのままにしてsecret_key_baseを新しく追加することで透過的にアップグレードされます。
  # config/initializers/secret_token.rb
  Myapp::Application.config.secret_token = 'existing secret token'
  Myapp::Application.config.secret_key_base = 'new secret key base'

注意:secret_key_baseを設定するのは、Rails 4.xへのユーザーベースの移行が100%完了し、Rails 3.xにロールバックする必要が完全になくなってからにしてください。これは、Rails 4.xの新しいsecret_key_baseを使用して署名されたcookiesにはRails 3.xのcookiesとの後方互換性がないためです。他のアップグレードが完全に完了するまでは、既存のsecret_tokenをそのままにしてsecret_key_baseを設定せず、非推奨警告を無視するという選択肢もあります。

外部アプリケーションやJavaScriptからRailsアプリケーションの署名付きセッションcookies (または一般の署名付きcookies) を読み出せる必要がある場合は、これらの問題を切り離すまではsecret_key_baseを設定しないでください。

  • Rails 4.0では、secret_key_baseが設定されているとcookieベースのセッションの内容が暗号化されます。Rails 3.xではcookieベースのセッションへの署名は行われますが暗号化は行われません。署名付きcookiesは、そのRailsアプリケーションで生成されたことが確認でき、不正が防止されるという意味では安全です。しかしセッションの内容はエンドユーザーから見えてしまいます。内容を暗号化することで懸念を取り除くことができ、パフォーマンスの低下もそれほどありません。

セッションcookiesを暗号化する方法の詳細についてはPull Request #9978 を参照してください。

  • Rails 4.0 ではActionController::Base.asset_pathオプションが廃止されました。代りにアセットパイプライン機能をご利用ください。

  • Rails 4.0ではActionController::Base.page_cache_extensionオプションが非推奨になりました。代りにActionController::Base.default_static_extensionをご利用ください。

  • Rails 4.0のAction PackからActionとPageのキャッシュ機能が取り除かれました。コントローラでcaches_actionを使用したい場合はactionpack-action_caching gemを、caches_pagesを使用したい場合はactionpack-page_caching gemをそれぞれGemfileに追加する必要があります。

  • Rails 4.0からXMLパラメータパーサーが取り除かれました。この機能が必要な場合はactionpack-xml_parser gemを追加する必要があります。

  • Rails 4.0のデフォルトのmemcachedクライアントがmemcache-clientからdalliに変更されました。アップグレードするには、単にgem 'dalli'Gemfileに追加します。

  • Rails 4.0ではコントローラでのdom_idおよびdom_classメソッドの使用が非推奨になりました (ビューでの使用は問題ありません)。この機能が必要なコントローラではActionView::RecordIdentifierモジュールをインクルードする必要があります。

  • Rails 4.0ではlink_toヘルパーでの:confirmオプションが非推奨になりました。代りにデータ属性を使用してください (例: data: { confirm: 'Are you sure?' }) link_to_iflink_to_unlessなどでも同様の対応が必要です。

  • Rails 4.0ではassert_generatesassert_recognizesassert_routingの動作が変更されましたこれらのアサーションからはActionController::RoutingErrorの代りにAssertionが発生するようになりました。

  • Rails 4.0では、名前付きルートの定義が重複している場合にArgumentErrorが発生するようになりました。このエラーは、明示的に定義された名前付きルートやresourcesメソッドによってトリガされます。名前付きルートexample_pathが衝突している例を2つ示します。

  get 'one' => 'test#example', as: :example
  get 'two' => 'test#example', as: :example

  resources :examples
  get 'clashing/:id' => 'test#example', as: :example

最初の例では、複数のルーティングで同じ名前を使用しないようにすれば回避できます。次の例では、onlyまたはexceptオプションをresourcesメソッドで使用することで、作成されるルーティングを制限することができます。詳細は Routing Guide を参照。

  • Rails 4.0ではunicode文字のルーティングの描出方法が変更されました。unicode文字を使用するルーティングを直接描出できるようになりました。既にこのようなルーティングを使用している場合は、以下の変更が必要です。
get Rack::Utils.escape('こんにちは'), controller: 'welcome', action: 'index'

上のコードは以下のように変更する必要があります。

get 'こんにちは', controller: 'welcome', action: 'index'

  • Rails 4.0でルーティングにmatchを使用する場合は、リクエストメソッドの指定が必須となりました。例:
  # Rails 3.x
  match '/' => 'root#index'

上のコードは以下のように変更する必要があります。
  match '/' => 'root#index', via: :get

  # またはま
  get '/' => 'root#index'

  • Rails 4.0からActionDispatch::BestStandardsSupportミドルウェアが削除されました。<!DOCTYPE html>は既に http://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx の標準モードをトリガするようになり、ChromeFrameヘッダはconfig.action_dispatch.default_headersに移動されました。

アプリケーションコード内にあるこのミドルウェアへの参照はすべて削除する必要がありますので注意が必要です。例:

# 例外発生
config.middleware.insert_before(Rack::Lock, ActionDispatch::BestStandardsSupport)

環境設定も確認し、config.action_dispatch.best_standards_supportがある場合は削除します。

  • Rails 4.0では、アセットのプリコンパイル時にvendor/assetsおよびlib/assetsから非JS/CSSアセットを自動的にはコピーしなくなりました。Railsアプリケーションとエンジンの開発者は、これらのアセットをapp/assetsに置き、config.assets.precompileを設定してください。

  • Rails 4.0では、リクエストされたフォーマットをアクションが扱わない場合にActionController::UnknownFormatが発生するようになりました。デフォルトでは、この例外は406 Not Acceptable応答として扱われますが、この動作をオーバーライドすることができます。Rails 3では常に406 Not Acceptableが返されます。オーバーライドはできません。

  • Rails 4.0では、ParamsParserがリクエストパラメータをパースできなかった場合に一般的なActionDispatch::ParamsParser::ParseError例外が発生するようになりました。MultiJson::DecodeErrorのような低レベルの例外の代りにこの例外をレスキューすることができます。

  • Rails 4.0では、URLプレフィックスで指定されたアプリケーションにエンジンがマウントされている場合にSCRIPT_NAMEが正しく入れ子になるようになりました。今後はURLプレフィックスの上書きを回避するためにdefault_url_options[:script_name]を設定する必要はありません。

  • Rails 4.0ではActionDispatch::Integrationの導入に伴いActionController::Integrationが非推奨となりました。

  • Rails 4.0ではActionDispatch::IntegrationTestの導入に伴いActionController::IntegrationTestは非推奨となりました。

  • Rails 4.0ではActionDispatch::PerformanceTestの導入に伴いActionController::PerformanceTestが非推奨となりました。

  • Rails 4.0ではActionDispatch::Requestの導入に伴いActionController::AbstractRequestが非推奨となりました。

  • Rails 4.0ではActionDispatch::Requestの導入に伴いActionController::Requestが非推奨となりました。

  • Rails 4.0ではActionDispatch::Responseの導入に伴いActionController::AbstractResponseが非推奨となりました。

  • Rails 4.0ではActionDispatch::Responseの導入に伴いActionController::Responseが非推奨となりました。

  • Rails 4.0ではActionDispatch::Routingの導入に伴いActionController::Routingが非推奨となりました。

3.8 Active Support

Rails 4.0ではERB::Util#json_escapeのエイリアスjが廃止されました。このエイリアスjは既にActionView::Helpers::JavaScriptHelper#escape_javascriptで使用されているためです。

3.9 ヘルパーの読み込み順序

Rails 4.0では複数のディレクトリからのヘルパーの読み込み順が変更されました。以前はいったんすべて集められてからアルファベット順にソートされていました。Rails 4.0にアップグレードすると、ヘルパーは読み込まれたディレクトリの順序を保持し、ソートは各ディレクトリ内でのみ行われます。helpers_pathパラメータを明示的に使用している場合を除いて、この変更はエンジンからヘルパーを読み込む方法にしか影響しません。ヘルパー読み込みの順序に依存している場合は、アップグレード後に正しいメソッドが使用できているかどうかを確認する必要があります。エンジンが読み込まれる順序を変更したい場合は、config.railties_order= メソッドを使用できます。

3.10 Active Record ObserverとAction Controller Sweeper

Active Record ObserverとAction Controller Sweeperはrails-observers gemに切り出されました。これらの機能が必要な場合はrails-observers gemを追加してください。

3.11 sprockets-rails

  • assets:precompile:primaryおよびassets:precompile:allは削除されました。assets:precompileを代りに使用してください。
  • config.assets.compressオプションは、たとえば以下のようにconfig.assets.js_compressor に変更する必要があります。
config.assets.js_compressor = :uglifier

3.12 sass-rails

  • 引数を2つ使用するasset-urlは非推奨となりました。たとえば、asset-url("rails.png", image)asset-url("rails.png")とする必要があります。

4 Rails 3.1からRails 3.2へのアップグレード

Railsアプリケーションのバージョンが3.1より前の場合、まず3.1へのアップグレードを完了してからRails 3.2へのアップグレードにとりかかってください。

以下の変更は、Rails 3.2.xの最新版であるRails 3.2.17にアップグレードするためのものです。

4.1 Gemfile

Gemfileを以下のように変更します。

gem 'rails', '3.2.17'

group :assets do
  gem 'sass-rails',   '~> 3.2.6'
  gem 'coffee-rails', '~> 3.2.2'
  gem 'uglifier',     '>= 1.0.3'
end

4.2 config/environments/development.rb

development環境にいくつかの新しい設定を追加する必要があります。

# Active Recordのモデルをマスアサインメントから保護するために例外を発生する
config.active_record.mass_assignment_sanitizer = :strict

# クエリの実行計画 (クエリプラン) を現在より多く出力する
# (SQLite、MySQL、PostgreSQLで動作)
config.active_record.auto_explain_threshold_in_seconds = 0.5

4.3 config/environments/test.rb

mass_assignment_sanitizer設定をconfig/environments/test.rbにも追加する必要があります。

# Active Recordのモデルをマスアサインメントから保護するために例外を発生する
config.active_record.mass_assignment_sanitizer = :strict

4.4 vendor/plugins

vendor/plugins はRails 3.2で非推奨となり、Rails 4.0では完全に削除されました。Rails 3.2へのアップグレードでは必須ではありませんが、今のうちにプラグインをgemにエクスポートしてGemfileに追加するのがよいでしょう。理由があってプラグインをgemにしないのであれば、プラグインをlib/my_plugin/*に移動し、適切な初期化の記述をconfig/initializers/my_plugin.rbに書いてください。

4.5 Active Record

:dependent => :restrictオプションがbelongs_toから削除されました。関連付けられたオブジェクトがある場合にこのオブジェクトを削除したくない場合は、:dependent => :destroyを設定し、関連付けられたオブジェクトのdestroyコールバックとの関連付けがあるかどうかを確認してからfalseを返すようにします。

5 Rails 3.0からRails 3.1へのアップグレード

Railsアプリケーションのバージョンが3.0より前の場合、まず3.0へのアップグレードを完了してからRails 3.1へのアップグレードにとりかかってください。

以下の変更は、Rails 3.1.xの最新版であるRails 3.1.12にアップグレードするためのものです。

5.1 Gemfile

Gemfileを以下のように変更します。

gem 'rails', '3.1.12'
gem 'mysql2' 

# 新しいアセットパイプラインで必要
group :assets do
  gem 'sass-rails',   '~> 3.1.7'
  gem 'coffee-rails', '~> 3.1.1'
  gem 'uglifier',     '>= 1.0.3'
end

# Rails 3.1からJQueryがデフォルトのJavaScriptライブラリになる
gem 'jquery-rails'

5.2 config/application.rb

アセットパイプラインを使用するために以下の変更が必要です。

config.assets.enabled = true
config.assets.version = '1.0'

Railsアプリケーションでリソースのルーティングに"/assets"ルートを使用している場合、コンフリクトを避けるために以下の変更を加えます。

# '/assets'のデフォルト
config.assets.prefix = '/asset-files'

5.3 config/environments/development.rb

RJS の設定config.action_view.debug_rjs = trueを削除してください。

アセットパイプラインを有効にしている場合は以下の設定を追加します。

# 開発環境ではアセットを圧縮しない
config.assets.compress = false

# アセットで読み込んだ行を展開する
config.assets.debug = true

5.4 config/environments/production.rb

以下の変更はほとんどがアセットパイプライン用です。詳細については アセットパイプライン ガイドを参照してください。

# JavaScriptとCSSを圧縮する
config.assets.compress = true

# プリコンパイル済みのアセットが見当たらない場合にアセットパイプラインにフォールバックしない
config.assets.compile = false

# アセットURLのダイジェストを生成する
config.assets.digest = true

# Rails.root.join("public/assets")へのデフォルト
# config.assets.manifest = 該当するパス

# 追加のアセット (application.js、application.cssおよびすべての非JS/CSSが追加済み) をプリコンパイルする
# config.assets.precompile += %w( search.js )

# アプリケーションへのすべてのアクセスを強制的にSSLにし、Strict-Transport-Securityとセキュアクッキーを使用する
# config.force_ssl = true

5.5 config/environments/test.rb

テスト環境に以下を追加することでテストのパフォーマンスが向上します。

# Cache-Controlを使用するテストで静的アセットサーバーを構成し、パフォーマンスを向上させる
config.serve_static_assets = true
config.static_cache_control = 'public, max-age=3600'

5.6 config/initializers/wrap_parameters.rb

ネストしたハッシュにパラメータを含めたい場合は、このファイルに以下のコンテンツを含めて追加します。新しいアプリケーションではこれがデフォルトになります。

# このファイルを変更後サーバーを必ず再起動してください。
# このファイルにはActionController::ParamsWrapper用の設定が含まれており
# デフォルトでオンになっています。

# JSON用にパラメータをラップします。:formatに空配列を設定することで無効にできます。
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end

# JSONのルート要素をデフォルトで無効にする
ActiveSupport.on_load(:active_record) do
  self.include_root_in_json = false
end

5.7 config/initializers/session_store.rb

何か新しいセッションキーを設定するか、すべてのセッションを削除するかのどちらかにする必要があります。

# config/initializers/session_store.rbに以下を設定する
AppName::Application.config.session_store :cookie_store, key: 'SOMETHINGNEW'

または

$ rake db:sessions:clear

5.8 ビューのアセットヘルパー参照から:cacheオプションと:concatオプションを削除する

  • Asset Pipelineの:cacheオプションと:concatは廃止されました。ビューからこれらのオプションを削除してください。

Feedback

You're encouraged to help improve the quality of this guide.

Please contribute if you see any typos or factual errors. To get started, you can read our documentation contributions section.

You may also find incomplete content, or stuff that is not up to date. Please do add any missing documentation for master. Make sure to check Edge Guides first to verify if the issues are already fixed or not on the master branch. Check the Ruby on Rails Guides Guidelines for style and conventions.

If for whatever reason you spot something to fix but cannot patch it yourself, please open an issue.

And last but not least, any kind of discussion regarding Ruby on Rails documentation is very welcome in the rubyonrails-docs mailing list.