Ruby on Rails 5.1 リリースノート

Rails 5.1 の注目ポイント

本リリースノートでは、主要な変更についてのみ説明します。多数のバグ修正および変更点については、GithubのRailsリポジトリにあるコミットリストのchangelogを参照してください。

1 Rails 5.1へのアップグレード

既存のアプリケーションをアップグレードするのであれば、その前に質のよいテストカバレッジを用意するのはよい考えです。アプリケーションがRails 5.0までアップグレードされていない場合は先にそれを完了し、アプリケーションが正常に動作することを十分確認してからRails 5.0にアップデートしてください。アップグレードの注意点などについてはRuby on Railsアップグレードガイド を参照してください。

2 主要な変更

2.1 Yarnのサポート

Pull Request

Rails 5.1より、JavaScriptの依存管理をnpmからYarnに変更できるようになりました。ReactやVueJSをはじめ、あらゆるnpmライブラリを簡単に利用できます。Yarnサポートはアセットパイプラインに統合されるので、あらゆるライブラリ依存がRails 5.1アプリケーションでシームレスに動作します。

2.2 Webpackのサポート(オプション)

Pull Request

新しいWebpacker gemの導入によって、JavaScriptのアセット用bundlerとも言うべきWebpackを簡単にRailsアプリケーションに統合できるようになりました。Railsアプリケーションを新規に生成するときに--webpackフラグを付けることで、Webpack統合が有効になります。

統合されたWebpackはアセットパイプラインとの完全互換が保たれます。画像・フォント・音声などのアセットも従来どおりアセットパイプラインで利用できます。また、一部のJavaScriptコードをアセットパイプラインで管理し、その他のJavaScriptコードをWebpack経由で処理する、といったこともできます。これらはすべて、デフォルトで有効なYarnで管理されます。

2.3 デフォルトでのjQuery依存を廃止

Pull Request

従来のRailsでは、data-remotedata-confirmについてはjQueryに依存し、その他の機能をUnobtrusive JavaScript(UJS: 控えめなJavaScript)に依存する形で機能を提供していました。Rails 5.1からはこれらの依存が解消され、UJSはvanilla JavaScript(=純粋なJavaScript)で書き直されました。このコードはAction View内部でrails-ujsとしてリリースされています。

デフォルトではjQueryに依存しなくなりましたが、必要に応じて従来どおりjQueryに依存することもできます。

2.4 システムテスト

Pull Request

Rails 5.1でCapybaraが標準サポートされ、システムテストの形式内でCapybaraでテストを書けるようになりました。今後はCapybaraの設定を気にする必要も、テストでデータベースのクリーニングを気にする必要もありません。Rails 5.1ではChrome用にテストを実行するためのラッパーが提供され、テスト失敗時に自動的にスクリーンショットを作成するなどの機能が追加されました。

2.5 秘密情報の暗号化

Pull Request

sekrets gemの手法にならい、Railsアプリケーションの秘密情報を安全に管理できるようになりました。

暗号化済みの秘密情報ファイルを生成するにはbin/rails secrets:setupを実行します。このコマンドを実行するとマスターキーも同時に生成されます(マスターキーはリポジトリには絶対保存しないでください)。これにより、暗号化された秘密情報ファイルをGitなどのリビジョンコントロールシステムに安全にチェックインできるようになります。

production環境では、マスターキーをRAILS_MASTER_KEY環境変数やキーファイルに保存することで、秘密情報の暗号は自動解除されます。

2.6 パラメータ化されたmailer

Pull Request

mailer用クラス内の全メソッドで利用する共通のパラメータを指定できるようになりました。これにより、インスタンス変数やヘッダーなどの共通設定を共有できます。

 class InvitationsMailer < ApplicationMailer
  before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
  before_action { @account = params[:inviter].account }

  def account_invitation
    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
  end 
end

InvitationsMailer.with(inviter: person_a, invitee: person_b)
                 .account_invitation.deliver_later

2.7 directルーティングとresolvedルーティング

Pull Request

Rails 5.1のルーティングDSLにresolvedirectという2つのメソッドが追加されました。resolveメソッドを使うと、モデルのポリモーフィックマッピングを以下のようにカスタマイズできます。

 resource :basket

resolve("Basket") { [:basket] }
<%= form_for @basket do |form| %>
  <!-- basket form -->
<% end %>

上の場合、従来の/baskets/:idではなく、単一の/basketというURLが生成されます。

directメソッドを使うと、以下のようにカスタムURLヘルパーメソッドを作成できます。

 direct(:homepage) { "http://www.rubyonrails.org" }

>> homepage_url
=> "http://www.rubyonrails.org"

ブロックの戻り値には、url_forメソッドに引数として渡せる有効なものを使う必要があります。つまり、directメソッドには、有効な文字列URL、ハッシュ、配列、Active Modelインスタンス、Active Modelクラスを渡せます。

 direct :commentable do |model|
  [ model, anchor: model.dom_id ]
end 

direct :main do
  { controller: 'pages', action: 'index', subdomain: 'www' }
end 

2.8 form_forとform_tagのform_withへの統合

Pull Request

Rails 5.1より前のHTMLフォーム生成メソッドは、モデルインスタンス用のform_forと、カスタムURL用のform_tagの2種類がありました。

Rails 5.1ではこの2つのインターフェイスをform_withに統合し、URLベース、スコープ、モデルを指定してformタグを生成できるようになりました。

URLのみを指定する場合は次のようにします。

<%= form_with url: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>

<%# ↓生成されるタグ %>

<form action="/posts" method="post" data-remote="true">
  <input type="text" name="title">
</form>

inputフィールド名にスコープをプレフィックスとして追加する場合は以下のようにします。

<%= form_with scope: :post, url: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>

<%# ↓生成されるタグ %>

<form action="/posts" method="post" data-remote="true">
  <input type="text" name="post[title]">
</form>

モデルを指定して、URLとスコープを自動推論させるには以下のようにします。

<%= form_with model: Post.new do |form| %>
  <%= form.text_field :title %>
<% end %>

<%# ↓生成されるタグ %>

<form action="/posts" method="post" data-remote="true">
  <input type="text" name="post[title]">
</form>

既存のモデルの場合は更新用フォームが生成され、フィールドに値が表示されます。

<%= form_with model: Post.first do |form| %>
  <%= form.text_field :title %>
<% end %>

<%# ↓生成されるタグ %>

<form action="/posts/1" method="post" data-remote="true">
  <input type="hidden" name="_method" value="patch">
  <input type="text" name="post[title]" value="<postのtitle>">
</form>

3 非互換性

以下の変更については、アップグレード時に対応が必要となることがあります。

3.1 複数接続を用いるトランザクションテスト

トランザクションテストでは、データベーストランザクションにおいてActive Recordのすべての接続がラップされるようになりました。

テスト中にスレッドが生成され、かつそれらのスレッドがデータベース接続を取得する場合は、データベース接続について特別の注意が必要になります。

マネージドトランザクション内において、スレッドは個数にかかわらず単一のデータベース接続を共有します。このため、データベース接続のステータスはすべてのスレッドから見て同じになり、最も外側のトランザクションは無視されます。従来、こうした追加接続はfixtureのrowなどを参照できませんでした。

ネストしたトランザクション内に入ったスレッドでは、独立性を保つために一時的に接続を専有します。

アプリケーションの現在のテストが、生成されたスレッド内で(トランザクションの外にある)接続を個別に取得することを前提としている場合は、接続を明示的に管理する必要があります。

ただし、明示的なデータベーストランザクションを利用するようテストを変更すると、テストで生成されるスレッドが互いに関連して動作する場合にデッドロックが発生する可能性があります。

この新しい振る舞いを無効にする簡単な方法は、影響を受けるすべてのテストケースでトランザクションテストを無効にすることです。

4 Railties

変更の詳細についてはChangelogを参照してください。

4.1 削除されたもの

  • 非推奨のconfig.static_cache_controlを削除 (commit)

  • 非推奨のconfig.serve_static_filesを削除 (commit)

  • 非推奨のrails/rack/debuggerファイルを削除 (commit)

  • 非推奨のタスクrails:updaterails:templaterails:template:copyrails:update:configsrails:update:binを削除

    (commit)

  • routesタスクで非推奨のCONTROLLER環境変数を削除 (commit)

  • rails newコマンドから -j (--javascript)オプションを削除 (Pull Request)

4.2 主な変更点

  • config/secrets.ymlに、全環境で読み込まれる共有のセクションを追加 (commit)

  • config/secrets.ymlですべてのキーをシンボルとして読み込むようになった (Pull Request)

  • デフォルトスタックからjquery-railsを削除: rails-ujsはAction Viewの一部としてリリースされ、デフォルトのUJSアダプタとしてインクルードされる (Pull Request)

  • 新しいアプリケーションでyarnをサポート: yarn binstubとpackage.jsonを追加 (Pull Request)

  • 新しいアプリケーションでWebpackをサポート: --webpackオプションを指定するとrails/webpacker gemに委譲される (Pull Request)

  • 新しいアプリケーションにGitリポジトリを追加(--skip-gitを指定しない場合) (Pull Request)

  • config/secrets.yml.encに暗号化済み秘密情報を追加 (Pull Request)

  • rails initializersにrailtieクラス名を表示 (Pull Request)

5 Action Cable

変更の詳細についてはChangelogを参照してください。

5.1 主な変更点

  • cable.ymlのRadisアダプタとイベントベースRedisのアダプタでchannel_prefixをサポート: 複数のRailsアプリケーションで同じRedisサーバーが使われている場合の名前衝突回避のため (Pull Request)

  • データブロードキャスティング用のActiveSupport::Notificationsフックを追加 (Pull Request)

6 Action Pack

変更の詳細についてはChangelogを参照してください。

6.1 削除されたもの

  • ActionDispatch::IntegrationTestクラスとActionController::TestCaseクラスで#process#get#post#patch#put#delete#headの非キーワード引数サポートを廃止 (Commit, Commit)

  • 非推奨のActionDispatch::Callbacks.to_prepareActionDispatch::Callbacks.to_cleanupを削除 (Commit)

  • コントローラのフィルタに関連する非推奨メソッドを削除 (Commit)

  • render メソッドのキーワード引数 :text:nothing のサポートを削除 (Commit, Commit)

  • ActionController::Parameters における HashWithIndifferentAccess のメソッド呼び出しのサポートを削除 (Commit)

6.2 非推奨

  • パスパラメータ:controller:actionを非推奨に指定。 (Pull Request)

  • config.action_controller.raise_on_unfiltered_parametersを非推奨に指定。Rails 5.1では既に無効。 (Commit)

6.3 主な変更点

  • ルーティングDSLにdirectメソッドとresolveメソッドを追加 (Pull Request)

  • アプリケーションのシステムテスト作成用クラス ActionDispatch::SystemTestCaseを追加 (Pull Request)

7 Action View

変更の詳細についてはChangelogを参照してください。

7.1 削除されたもの

  • 非推奨の#original_exceptionActionView::Template::Errorから削除 (commit)

  • strip_tagsencode_special_charsの名前誤りを修正 (Pull Request)

7.2 非推奨

  • Erubis(ERBハンドラ)を非推奨化: 今後はErubiに (Pull Request)

7.3 主な変更点

  • Rails 5のデフォルトであるrawテンプレートハンドラからHTMLセーフな文字列を出力するようになった (commit)

  • datetime_fielddatetime_field_tagdatetime-localフィールドを生成するよう変更 (Pull Request)

  • HTMLタグ用の新しいビルダ風の構文を導入(tag.divtag.brなど) (Pull Request)

  • form_tagform_forを統合するform_withを追加 (Pull Request)

  • check_parametersオプションをcurrent_page?に追加 (Pull Request)

8 Action Mailer

変更の詳細についてはChangelogを参照してください。

8.1 主な変更点

  • 例外ハンドリング: mailerのアクション・メッセージ配信・遅延した配信ジョブによってraiseした例外をrescue_fromで扱うように変更 (commit)

  • ファイルが添付されbodyがインラインに設定されている場合にもcontent typeをカスタマイズできるようになった (Pull Request)

  • defaultメソッドにlambdaを値として渡せるようになった (Commit)

  • mailerでパラメータ付き呼び出しがサポートされた: mailerアクション間でのbeforeフィルタやdefaultsの共有に使う (Commit)

  • mailerアクションで受け取った引数をargsキーのprocess.action_mailerイベントに渡せるようになった (Pull Request)

9 Active Record

変更の詳細については、Changelogを参照してください。

9.1 削除されたもの

  • ActiveRecord::QueryMethods#selectに引数とブロックを同時に渡せるサポートを削除 (Commit)

  • 非推奨のactiverecord.errors.messages.restrict_dependent_destroy.oneactiverecord.errors.messages.restrict_dependent_destroy.many i18nスコープを削除 (Commit)

  • singularとcollectionにある関連付け読み出しメソッドreaderから引数の強制再読込オプション(非推奨)を削除 (Commit)

  • #quoteにカラムを渡すサポート(非推奨)を削除 (Commit)

  • #tablesメソッドからname引数(非推奨)を削除 (Commit)

  • #tables#table_exists?から非推奨の動作を削除: #table_exists?がテーブルとビューを両方返していたのをテーブルだけを返すようになった (Commit)

  • ActiveRecord::StatementInvalid#initializeActiveRecord::StatementInvalid#original_exceptionから非推奨のoriginal_exception引数を削除 (Commit)

  • クエリにクラスを値として渡せるサポート(非推奨)を削除 (Commit)

  • LIMITにカンマを使うクエリのサポート(非推奨)を削除 (Commit)

  • #destroy_allから非推奨のconditionsパラメータを削除 (Commit)

  • #delete_allから非推奨のconditionsパラメータを削除 (Commit)

  • 非推奨の#load_schema_forを削除して#load_schemaに置き換え (Commit)

  • 非推奨の#raise_in_transactional_callbacks設定を削除 (Commit)

  • 非推奨の#use_transactional_fixtures設定を削除 (Commit)

9.2 非推奨

  • error_on_ignored_order_or_limitフラグを非推奨化: 今後はerror_on_ignored_orderを使用 (Commit)

  • sanitize_conditionsを非推奨化: 今後はsanitize_sqlを使用 (Pull Request)

  • 接続アダプタのDeprecated supports_migrations?を非推奨化 (Pull Request)

  • Migrator.schema_migrations_table_nameを非推奨化: 今後は,SchemaMigration.table_nameを使用 (Pull Request)

  • 引用符追加や型変換で使われていた#quoted_idを非推奨化 (Pull Request)

  • #index_name_exists?defaultを渡すことを非推奨化 (Pull Request)

9.3 主な変更点

  • 主キーのデフォルト型をBIGINTに変更 (Pull Request)

  • virtualカラムとgeneratedカラムのサポート(MySQL 5.7.5+、MariaDB 5.2.0+) (Commit)

  • バッチ処理を制限するサポートを追加 (Commit)

  • データベーストランザクション内のすべてのActive Record接続をトランザクションテストでラップするようになった (Pull Request)

  • mysqldumpコマンドの出力に含まれるコメントをデフォルトでスキップするようになった (Pull Request)

  • ActiveRecord::Relation#countの修正: 従来は引数にブロックを渡すとエラーなしで無視されたが、RubyのEnumerable#countでレコード数をカウントするようになった (Pull Request)

  • psqlコマンドに"-v ON_ERROR_STOP=1"フラグを渡し、SQLエラー出力を抑制しないようになった (Pull Request)

  • ActiveRecord::Base.connection_pool.statを追加 (Pull Request)

  • ActiveRecord::Migrationを直接継承するとエラーをraiseするようになった: 今後はマイグレーションの対象となるRailsバージョンを指定する必要がある (Commit)

  • through関連付けにあいまいなreflection名がある場合にエラーをraiseするようになった (Commit)

10 Active Model

変更の詳細についてはChangelogを参照してください。

10.1 削除されたもの

  • ActiveModel::Errorsの非推奨のメソッドを削除 (commit)

  • lengthバリデータから非推奨の:tokenizerオプションを削除 (commit)

  • 戻り値がfalseの場合にコールバックを停止する動作(非推奨)を削除 (commit)

10.2 主な変更点

  • モデルの属性への関連付けに使われる元の文字列が誤ってfrozenにならないようになった (Pull Request)

11 Active Job

変更の詳細についてはChangelogを参照してください。

11.1 削除されたもの

  • .queue_adapterにアダプタのクラスを渡すサポート(非推奨)を削除 (commit)

  • ActiveJob::DeserializationErrorから非推奨の#original_exceptionを削除 (commit)

11.2 主な変更点

  • ActiveJob::Base.retry_onActiveJob::Base.discard_onによる宣言的な例外ハンドリングを追加 (Pull Request)

  • yieldされるジョブインスタンスで、リトライ失敗後にカスタムロジックでjob.argumentsなどにアクセスできるようになった (commit)

12 Active Support

変更の詳細についてはChangelogを参照してください。

12.1 削除されたもの

  • ActiveSupport::Concurrency::Latchクラスを削除 (Commit)

  • halt_callback_chains_on_return_falseを削除 (Commit)

  • 戻り値がfalseの場合にコールバックを停止する動作(非推奨)を削除 (Commit)

12.2 非推奨

  • トップレベルのHashWithIndifferentAccessクラスをやや弱めに非推奨化: 今後はActiveSupport::HashWithIndifferentAccessクラスを使用 (Pull Request)

  • set_callbackskip_callback:if条件オプションや:unless条件オプションに文字列を渡すことを非推奨化 (Commit)

12.3 主な変更点

  • 期間の解析や移動をDSTの変更全体に渡って統一した (Commit, Pull Request)

  • Unicodeバージョンを9.0.0にアップデート (Pull Request)

  • Duration#before#agoのエイリアス)と#after(#since`のエイリアス)を追加 (Pull Request)

  • Module#delegate_missing_toを追加: 現在のオブジェクトで定義されていない、(プロキシオブジェクトへの)メソッド呼び出しの委譲に使う (Pull Request)

  • Date#all_dayを追加: 現在の日時の「その日全体」を表す期間を返す (Pull Request)

  • テスト用のassert_changesメソッドとassert_no_changesメソッドを導入 (Pull Request)

  • travelメソッドとtravel_toメソッドが、ネストした呼び出しでエラーをraiseするようになった (Pull Request)

  • DateTime#changeを更新し、usecとnsecをサポート (Pull Request)

13 クレジット表記

Railsを頑丈かつ安定したフレームワークにするために多大な時間を費やしてくださった多くの開発者については、Railsコントリビューターの完全なリストを参照してください。これらの方々全員に深く敬意を表明いたします。