Rails 4.1の注目ポイント
config/secrets.yml本リリースノートでは、主要な変更についてのみ説明します。細かなバグ修正や変更については、change logを参照するか、GitHubの主要なRailsリポジトリにあるコミットリストを参照してください。
既存のアプリケーションをアップグレードするのであれば、その前に質のよいテストカバレッジを用意するのがよい考えです。アプリケーションがRails 4.0までアップグレードされていない場合は先にそれを完了し、アプリケーションが正常に動作することを十分確認してからRails 4.1にアップデートしてください。アップグレードの注意点などについてはRuby on Railsアップグレードガイドを参照してください。
SpringはRailsアプリケーション用のプリローダーです。アプリケーションをバックグラウンドで常駐させることで開発速度を向上させ、テストやrakeタスク、マイグレーションを実行するたびにRailsを起動しないで済むようにします。
Rails 4.1アプリケーションに含まれるbinstubは「spring化」されています。これは、アプリケーションのルートディレクトリでbin/railsおよびbin/rakeを実行すると自動的にspring環境をプリロードするということです。
rakeタスクの実行:
bin/rake test:models
Railsコマンドの実行:
bin/rails console
Springの状態確認:
$ bin/spring status Spring is running: 1182 spring server | my_app | started 29 mins ago 3656 spring app | my_app | started 23 secs ago | test mode 3746 spring app | my_app | started 10 secs ago | development mode
Springのすべての機能についてはSpring READMEを参照してください。
Ruby on Railsアップグレードガイドには、この機能を既存のアプリケーションと統合する方法について記載されています。
config/secrets.ymlRails 4.1ではconfigフォルダ内に新しくsecrets.ymlファイルが生成されます。デフォルトでは、このファイルにはアプリケーションのsecret_key_baseが含まれていますが、外部API用のアクセスキーなどの秘密キーもここに保存できます。
このファイルに保存された秘密キーはRails.application.secretsを用いてアクセスできます。
たとえば、以下のconfig/secrets.ymlについて見てみましょう。
development: secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 some_api_key: SOMEKEY
上の設定にした場合、development環境でRails.application.secrets.some_api_keyを実行するとSOMEKEYが返されます。
既存のアプリケーションにこの機能を統合する方法についてはRuby on Railsアップグレードガイドを参照してください。
スマートフォン、タブレット、デスクトップブラウザごとに異なるHTML/JSON/XMLテンプレートを使いたいことはよくあります。Variantを使うことで、これを簡単に実現できます。
リクエストvariantは、:tablet、:phone、:desktopのようなリクエストフォーマットを特殊化したものです。
before_actionで以下のvariantを設定できます。
request.variant = :tablet if request.user_agent =~ /iPad/
アクションの側では、フォーマットへの応答と同じ要領でvariantに応答します。
respond_to do |format| format.html do |html| html.tablet # renders app/views/projects/show.html+tablet.erb html.phone { extra_setup; render ... } end end
フォーマットごと、variantごとに個別のテンプレートを用意してください。
app/views/projects/show.html.erb app/views/projects/show.html+tablet.erb app/views/projects/show.html+phone.erb
以下のようなインライン文法を使うことで、variant定義を簡略化することもできます。
respond_to do |format| format.js { render "trash" } format.html.phone { redirect_to progress_path } format.html.none { render "trash" } end
Action Mailerプレビューは、特定のURLにアクセスすることで、送信されるメールがどんなふうに見えるかをレンダリングしてプレビューします。
チェックしたいメールオブジェクトを返すメソッドを持つプレビュークラスを定義してください。
class NotifierPreview < ActionMailer::Preview def welcome Notifier.welcome(User.first) end end
このプレビューを表示するには、http://localhost:3000/rails/mailers/notifier/welcomeにアクセスします。プレビューのリストはhttp://localhost:3000/rails/mailersで表示できます。
デフォルトのプレビュークラスはtest/mailers/previewsに置かれます。
preview_pathオプションを変更することでこれを変更できます。
詳細についてはドキュメントを参照してください。
データベースで値をintegerにマップしたい場所でenum属性を宣言しますが、名前でクエリを発行することもできます。
class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end conversation.archived! conversation.active? # => false conversation.status # => "archived" Conversation.archived # => Relation for all archived Conversations Conversation.statuses # => { "active" => 0, "archived" => 1 }
詳細についてはマニュアルを参照してください。
メッセージベリファイア(message verifier)は、署名付きメッセージの生成と照合に利用できます。この機能は、「パスワードを保存(remember me)」トークンや友人リストのような機密データを安全に転送するときに便利です。
Rails.application.message_verifierメソッドは、secret_key_baseで生成されたキーで署名された新しいメッセージベリファイアと、与えられたメッセージ照合名を返します。
signed_token = Rails.application.message_verifier(:remember_me).generate(token) Rails.application.message_verifier(:remember_me).verify(signed_token) # => token Rails.application.message_verifier(:remember_me).verify(tampered_token) # ActiveSupport::MessageVerifier::InvalidSignatureを発生する
自然かつ堅苦しくない方法で、クラスから責任を分離します。
class Todo < ActiveRecord::Base concerning :EventTracking do included do has_many :events end def latest_event ... end private def some_internal_method ... end end end
この例は、EventTrackingモジュールをインラインで定義し、ActiveSupport::Concernでextendし、Todoクラスにミックスインしたのと同等です。
詳細および想定されるユースケースについてはマニュアルを参照してください。
<script>タグにCSRF保護を実施JavaScriptレスポンスを伴うGETリクエストもクロスサイトリクエストフォージェリ(CSRF)保護の対象となりました。この保護によって、第三者のサイトが重要なデータの奪取のために自分のサイトのJavaScript URLを参照して実行しようとすることを防止します。
これは、xhrを使わない場合、.js URLにヒットするすべてのテストはCSRF保護によって失敗するということです。`XmlHttpRequestsを明示的に想定するようにテストをアップグレードしてください。post :create, format: :jsの代わりに、明示的にxhr :post, :create, format: :jsをお使いください。
変更の詳細についてはChangelogを参照してください。
update:application_controller rake taskが削除されました。
非推奨のRails.application.railties.enginesが除外されました。
非推奨のthreadsafe!がRails Configから削除されました。
非推奨のActiveRecord::Generators::ActiveModel#update_attributesが削除されました。ActiveRecord::Generators::ActiveModel#updateをお使いください。
非推奨のconfig.whiny_nilsオプションが削除されました。
非推奨のテスト実行rakeタスクrake test:uncommittedおよびrake test:recentが削除されました。
Springアプリケーションプリローダーは新規アプリケーションにデフォルトでインストールされます。Gemfileのdevelopグループにインストールされ、productionグループにはインストールされません。(プルリク)
テスト失敗時にフィルタされていないバックトレースを表示するBACKTRACE環境変数。(コミット)
MiddlewareStack#unshiftが環境構成用に公開されました。(プルリク)
メッセージベリファイアを返すApplication#message_verifierメソッド。(プルリク)
デフォルトで生成されるテストヘルパーでrequireされるtest_help.rbファイルは、db/schema.rb(またはdb/structure.sql)を用いて自動的にテストデータベースを最新の状態に保ちます。スキーマを再度読み込んでもペンディング中のマイグレーションをすべて解決できなかった場合はエラーが発生します。config.active_record.maintain_test_schema = falseを指定することでエラーを回避できます。(プルリク)
Gem::Version.new(Rails.version)を返す便利なメソッドとしてRails.gem_versionが導入されました。より信頼できるバージョン比較法を提供します。(プルリク)
変更の詳細についてはChangelogを参照してください。
非推奨の、結合テスト用Railsアプリケーションフォールバックが削除されました。ActionDispatch.test_appを代わりにお使いください。
非推奨のpage_cache_extensionコンフィグが削除されました。
非推奨のActionController::RecordIdentifierが削除されました。ActionView::RecordIdentifierを代わりにお使いください。
以下の非推奨の定数がAction Controllerから削除されました。
| 削除された | 今後使う |
|---|---|
| ActionController::AbstractRequest | ActionDispatch::Request |
| ActionController::Request | ActionDispatch::Request |
| ActionController::AbstractResponse | ActionDispatch::Response |
| ActionController::Response | ActionDispatch::Response |
| ActionController::Routing | ActionDispatch::Routing |
| ActionController::Integration | ActionDispatch::Integration |
| ActionController::IntegrationTest | ActionDispatch::IntegrationTest |
protect_from_forgeryによって、クロスオリジン<script>タグも利用できなくなりました。テストをアップデートして、get :foo, format: :jsの代わりにxhr :get, :foo, format: :jsを使うようにしてください。(プルリク)
#url_forは、オプションのハッシュを配列の中で使えるようになりました。(プルリク)
session#fetchメソッドが追加されました。この振る舞いはHash#fetchと似ていますが、戻り値が常にセッションに保存される点が異なります。(プルリク)
Action ViewはAction Packから完全に分離されました。(プルリク)
deep_mungeに影響されているキーがログ出力されるようになりました。(プルリク)
セキュリティ脆弱性CVE-2013-0155に対応するため、パラメータのdeep_munge化を回避するconfig.action_dispatch.perform_deep_mungeconfigオプションが新たに追加されました。(プルリク)
署名及び暗号化されたcookies jarのシリアライザを指定するconfig.action_dispatch.cookies_serializerconfigオプションが新たに追加されました。(プルリク1、2/詳細)
変更の詳細についてはChangelogを参照してください。
37 Signals社のmail_view gemを元にメーラーのプレビュー機能が追加されました。(コミット)
Action Mailerメッセージの生成が計測されるようになりました。メッセージを生成するのにかかった時間がログに記録されます。(プルリク)
変更の詳細についてはChangelogを参照してください。
SchemaCacheメソッド(primary_keys、tables、columns、columns_hash)にnilを渡す非推奨機能が削除されました。
非推奨のブロックフィルタがActiveRecord::Migrator#migrateから削除されました。
非推奨のStringコンストラクタがActiveRecord::Migratorから削除されました。
scopeで呼び出し可能オブジェクトを渡さない用法が削除されました。
非推奨のtransaction_joinable=が削除されました。:joinableオプション付きでbegin_transactionをお使いください。
非推奨のdecrement_open_transactionsが削除されました。
非推奨のincrement_open_transactionsが削除されました。
非推奨のPostgreSQLAdapter#outside_transaction?メソッドが削除されました。代わりに#transaction_open?をお使いください。
非推奨のActiveRecord::Fixtures.find_table_nameが削除されました。ActiveRecord::Fixtures.default_fixture_model_nameをお使いください。
非推奨のcolumns_for_removeがSchemaStatementsから削除されました。
非推奨のSchemaStatements#distinctが削除されました。
非推奨のActiveRecord::TestCaseがRailsテストスイートに移動しました。このクラスはpublicでなくなり、Railsテストの内部でのみ使われます。
関連付けの:dependentで、非推奨の:restrictオプションのサポートが削除されました。
関連付けにおいて、非推奨の:delete_sql、:insert_sql、:finder_sql、:counter_sqlオプションが削除されました。
Columnから非推奨のtype_cast_codeが削除されました。
非推奨のActiveRecord::Base#connectionメソッドが削除されました。このメソッドにはクラス経由でアクセスするようにしてください。
auto_explain_threshold_in_secondsにおける非推奨の警告が削除されました。
Relation#countから非推奨の:distinctオプションが削除されました。
非推奨のpartial_updates、partial_updates?、partial_updates=が削除されました。
非推奨のscopedメソッドが削除されました。
非推奨のdefault_scopes?が削除されました。
4.0で非推奨だった、暗黙の結合参照が削除されました。
依存関係としてのactiverecord-deprecated_findersが削除されました。詳細についてはgem READMEを参照してください。
implicit_readonlyの用法が削除されました。明示的にreadonlyメソッドを用いてレコードをreadonlyに設定してください。(プルリク)
quoted_locking_columnメソッドは非推奨です。現在使われている場所はありません。
ConnectionAdapters::SchemaStatements#distinctは内部で使われなくなったため非推奨です。(プルリク)
rake db:test:*タスクは非推奨となりました。データベースは自動的にメンテナンスされます。railtiesのリリースノートを参照してください。(プルリク)
使われていないActiveRecord::Base.symbolized_base_class、および置き換えのないActiveRecord::Base.symbolized_sti_nameは非推奨になりました。コミット
デフォルトのスコープは、条件を連鎖した場合にオーバーライドされなくなりました。
今回の変更より前にモデルでdefault_scopeを定義していた場合、同じフィールドで条件が連鎖している場合にはオーバーライドされていました。現在は、他のスコープと同様、マージされるようになりました。詳細
モデルの属性やメソッドから派生する便利な "pretty" URL用にActiveRecord::Base.to_paramが追加されました。(プルリク)
ActiveRecord::Base.no_touchingが追加されました。モデルへのタッチを無視します。(プルリク)
MysqlAdapterおよびMysql2Adapterにおける型変換の真偽値が統一されました。type_castはtrueの場合に1を、falseの場合に2を返します。(プルリク)
.unscopeを指定するとdefault_scopeで指定された条件が削除されます。(コミット)
ActiveRecord::QueryMethods#rewhereが追加されました。既存の名前付きwhere条件をオーバーライドします。(コミット)
ActiveRecord::Base#cache_keyが拡張され、timestamp属性のリストをオプションで取れるようになりました。timestamp属性リストのうち最大値が使われます。(コミット)
enum属性を宣言するActiveRecord::Base#enumが追加されました。enum属性はデータベースのintegerにマップされますが、名前でクエリできます。(コミット)
JSON値が書き込み時に型変換されます。これにより値がデータベースからの読み出し時と一貫します。(プルリク)
hstore値が書き込み時に型変換されます。これにより値がデータベースからの読み出し時と一致します。(コミット)
サードパーティ製ジェネレータ用に、next_migration_numberがアクセス可能になりました。(プルリク)
引数をnilにしてupdate_attributesを呼び出すと、常にArgumentErrorエラーが発生します。具体的には、渡された引数がstringify_keysに応答しない場合にエラーが発生します。(プルリク)
(has_manyなどでの)CollectionAssociation#first/#lastによる結果の取り出しで、コレクション全体を読み出すクエリの代わりに、限定的なクエリが使われるようになりました。(プルリク)
Active Recordモデルクラスのinspectは新しい接続を初期化しなくなりました。つまり、データベースが見つからない状態でinspectを呼び出した場合に例外を発生しなくなりました。(プルリク)
countのカラム制約が削除されました。SQLが無効な場合にはデータベース側でraiseされます。(プルリク)
Railsが逆関連付けを自動で検出するようになりました。関連付けで:inverse_ofオプションを設定していない場合、Active Recordはヒューリスティックに逆関連付けを推測します。(プルリク)
ActiveRecord::Relationの属性のエイリアスを扱うようになりました。シンボルキーを使うと、ActiveRecordはエイリアス化された属性名をデータベース上の実際のカラム名に翻訳します。(プルリク)
フィクスチャーのERBファイルはメインオブジェクトのコンテキストでは評価されなくなりました。複数のフィクスチャーで使われているヘルパーメソッドは、ActiveRecord::FixtureSet.context_classでインクルードされるモジュール上で定義しておく必要があります。(プルリク)
RAILS_ENVが明示的に指定されている場合はテストデータベースのcreateやdropは行いません。(プルリク)
Relationに#map!や#delete_ifなどのミューテーターメソッド(mutator method)が含まれなくなりました。これらのメソッドを使いたい場合は#to_aを呼び出してArrayに変更してからにしてください。(プルリク)
find_in_batches、find_each、Result#each、Enumerable#index_byは、自身のサイズを計算可能なEnumeratorを返すようになりました。(プルリク)
scope、enumとAssociationsで "dangerous" 名前衝突が発生するようになりました。(プルリク, プルリク)
secondからfifthメソッドはfirstファインダーと同様に動作します。(プルリク)
touchがafter_commitとafter_rollbackコールバックを発火するようになりました。(プルリク)
sqlite >= 3.8.0でのパーシャルインデックスが有効になりました。(プルリク)
change_column_nullが復元可能になりました。(コミット)
マイグレーション後無効になったスキーマダンプにフラグが追加されました。これは新しいアプリケーションのproduction環境ではデフォルトでfalseに設定されます。(プルリク)
変更の詳細についてはChangelogを参照してください。
Validator#setupは非推奨です。今後はバリデーターのコンストラクタ内で手動で行なう必要があります。(コミット)ActiveModel::Dirtyに、状態を制御する新しいAPIreset_changesおよびchanges_appliedが追加されました。
検証の定義時に複数のコンテキストを指定できるようになりました。(プルリク)
attribute_changed?がハッシュを受け付けるようになり、属性が与えられた値に変更されたか(または与えられた値から変更されたか)どうかをチェックするようになりました。(プルリク)
変更の詳細についてはChangelogを参照してください。
MultiJSON依存が削除されました。これにより、ActiveSupport::JSON.decodeはMultiJSONのオプションハッシュを受け付けなくなりました。(プルリク / 詳細)
カスタムオブジェクトをJSONにエンコードするencode_jsonフックのサポートが削除されました。この機能はactivesupport-json_encoder gemに書き出されました。
この機能はactivesupport-json_encoder gemに書き出されました。
非推奨のActiveSupport::JSON::Variableが代替なしで削除されました。
非推奨のString#encoding_aware?コア拡張(core_ext/string/encoding)が削除されました。
非推奨のModule#local_constant_namesが削除されました。Module#local_constantsをお使いください。
非推奨のDateTime.local_offsetが削除されました。DateTime.civil_from_formatをお使いください。
非推奨のLoggerコア拡張(core_ext/logger.rb)が削除されました。
非推奨のTime#time_with_datetime_fallback、Time#utc_time、Time#local_timeが削除されました。Time#utcおよびTime#localをお使いください。
非推奨のHash#diffが代替なしで削除されました。
非推奨のDate#to_time_in_current_zoneが削除されました。Date#in_time_zoneをお使いください。
非推奨のProc#bindが代替なしで削除されました。
非推奨のArray#uniq_byとArray#uniq_by!が削除されました。ネイティブのArray#uniqおよびArray#uniq!をお使いください。
非推奨のActiveSupport::BasicObjectが削除されました。ActiveSupport::ProxyObjectをお使いください。
非推奨のBufferedLoggerが削除されました。ActiveSupport::Loggerをお使いください。
非推奨のassert_presentメソッドとassert_blankメソッドが削除されました。assert object.blank?およびassert object.present?をお使いください。
フィルタオブジェクト用の非推奨#filterメソッドが削除されました。対応する別のメソッドをお使いください(before filterの#beforeなど)。
デフォルトの活用形から不規則活用の'cow' => 'kine'が削除されました。(コミット)
時間表現Numeric#{ago,until,since,from_now}が非推奨になりました。この値はAS::Durationに明示的に変換してください。例: 5.ago => 5.seconds.ago (プルリク)
requireパスactive_support/core_ext/object/to_jsonが非推奨になりました。active_support/core_ext/object/jsonを代わりにrequireしてください。(プルリク)
ActiveSupport::JSON::Encoding::CircularReferenceErrorが非推奨になりました。この機能はactivesupport-json_encoder gemに書き出されました。(プルリク / 詳細)
ActiveSupport.encode_big_decimal_as_stringオプションが非推奨になりました。この機能はactivesupport-json_encoder gemに書き出されました。
(プルリク / 詳細)
カスタムのBigDecimalシリアライズが非推奨になりました。(プルリク)
ActiveSupportのJSONエンコーダーが書き直され、pure-RubyのカスタムエンコーディングではなくJSON gemを利用するようになりました。
(プルリク / 詳細)
ActiveSupport::Testing::TimeHelpers#travelおよび#travel_toが追加されました。これらのメソッドは、Time.nowおよびDate.todayをスタブ化することによって、現在時刻を指定の時刻または時間に変換します。
ActiveSupport::Testing::TimeHelpers#travel_backが追加されました。このメソッドは、travelおよびtravel_toメソッドによって追加されたスタブを削除することで、現在時刻を元の状態に戻します。(プルリク)
Numeric#in_millisecondsが追加されました。1.hour.in_millisecondsのように利用でき、これをgetTime()などのJavaScript関数に渡すことができます。(コミット)
Date#middle_of_day、DateTime#middle_of_day、Time#middle_of_dayメソッドが追加されました。エイリアスとしてmidday、noon、at_midday、at_noon、at_middle_of_dayも追加されました。(プルリク)
期間を生成するためのDate#all_week/month/quarter/yearが追加されました。(プルリク)
Time.zone.yesterdayとTime.zone.tomorrowが追加されました。(プルリク)
よく使われるString#gsub("pattern,'')の省略表現としてString#remove(pattern)が追加されました。(コミット)
値がnilの項目をハッシュから削除するためのHash#compactおよびHash#compact!が追加されました。(プルリク)
blank?およびpresent?はシングルトンを返します。(コミット)
新しいI18n.enforce_available_localesコンフィグのデフォルトはtrueです。これは、ロケールに渡されたI18nがavailable_localesリストに載っていなければならないということです。(プルリク)
Module#concerningが導入されました。自然かつ堅苦しくない方法で、クラスから責任を分離します。(コミット)
Object#presence_inが追加されました。値を単に許可済みリストに追加します。(コミット)膨大な時間を費やしてRailsを作り、頑丈かつ安定したフレームワークにしてくれた多くの皆様については、Railsコントリビューターの完全なリストを参照してください。これらの方々全員に敬意を表明いたします。
Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。
原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨
本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。
Railsガイド運営チーム (@RailsGuidesJP)
Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。