1 Rails 4.1へのアップグレード
既存のアプリケーションをアップグレードするのであれば、その前に質のよいテストカバレッジを用意するのがよい考えです。アプリケーションがRails 4.0までアップグレードされていない場合は先にそれを完了し、アプリケーションが正常に動作することを十分確認してからRails 4.1にアップデートしてください。アップグレードの注意点などについてはRuby on Railsアップグレードガイド を参照してください。
2 主要な変更
2.1 「Spring」アプリケーションプリローダー
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アップグレードガイドには、この機能を既存のアプリケーションと統合する方法について記載されています。
2.2 config/secrets.yml
Rails 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アップグレードガイドを参照してください。
2.3 Action Pack Variant
スマートフォン、タブレット、デスクトップブラウザごとに異なる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
2.4 Action Mailerプレビュー
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
オプションを変更することでこれを変更できます。
詳細についてはドキュメントを参照してください。
2.5 Active Record enums
データベースで値を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 }
詳細についてはマニュアルを参照してください。
2.6 メッセージベリファイア
メッセージベリファイア (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を発生する
2.7 Module#concerning
自然かつ堅苦しくない方法で、クラスから責任を分離します。
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
クラスにミックスインしたのと同等です。
詳細および想定されるユースケースについてはマニュアル を参照してください。
2.8 リモート <script>
タグにCSRF保護を実施
JavaScriptレスポンスを伴うGETリクエストもクロスサイトリクエストフォージェリ (CSRF) 保護の対象となりました。この保護によって、第三者のサイトが重要なデータの奪取のために自分のサイトのJavaScript URLを参照して実行しようとすることを防止します。
これは、xhr
を使わない場合、.js
URLにヒットするすべてのテストはCSRF保護によって失敗するということです。`XmlHttpRequests
を明示的に想定するようにテストをアップグレードしてください。post :create, format: :js
の代りに、明示的にxhr :post, :create, format: :js
をお使いください。
3 Railties
変更の詳細についてはChangelog を参照してください。
3.1 削除されたもの
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
が削除されました。
3.2 主な変更点
Springアプリケーションプリローダー は新規アプリケーションにデフォルトでインストールされます。
Gemfile
のdevelopグループにインストールされ、productionグループにはインストールされません。(Pull Request)テスト失敗時にフィルタされていないバックトレースを表示する
BACKTRACE
環境変数。(Commit)MiddlewareStack#unshift
が環境構成用に公開されました。(Pull Request)メッセージベリファイアを返す
Application#message_verifier
メソッド。(Pull Request)デフォルトで生成されるテストヘルパーでrequireされる
test_help.rb
ファイルは、db/schema.rb
(またはdb/structure.sql
) を用いて自動的にテストデータベースを最新の状態に保ちます。スキーマを再度読み込んでもペンディング中のマイグレーションをすべて解決できなかった場合はエラーが発生します。config.active_record.maintain_test_schema = false
を指定することでエラーを回避できます。(Pull Request)Gem::Version.new(Rails.version)
を返す便利なメソッドとしてRails.gem_version
が導入されました。より信頼できるバージョン比較法を提供します。(Pull Request)
4 Action Pack
変更の詳細についてはChangelog を参照してください。
4.1 削除されたもの
非推奨の、結合テスト用Railsアプリケーションフォールバックが削除されました。
ActionDispatch.test_app
を代りにお使いください。非推奨の
page_cache_extension
configが削除されました。非推奨の
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 |
4.2 主な変更点
protect_from_forgery
によって、クロスオリジン<script>
タグも利用できなくなりました。テストをアップデートして、get :foo, format: :js
の代りにxhr :get, :foo, format: :js
を使うようにしてください。(Pull Request)#url_for
は、オプションのハッシュを配列の中で使えるようになりました。(Pull Request)session#fetch
メソッドが追加されました。この振る舞いはHash#fetchと似ていますが、戻り値が常にセッションに保存される点が異なります。(Pull Request)Action ViewはAction Packから完全に分離されました。(Pull Request)
deep_mungeに影響されているキーがログ出力されるようになりました。(Pull Request)
セキュリティ脆弱性CVE-2013-0155に対応するため、パラメータのdeep_munge化を回避する
config.action_dispatch.perform_deep_munge
configオプションが新たに追加されました。(Pull Request)署名及び暗号化されたcookies jarのシリアライザを指定する
config.action_dispatch.cookies_serializer
configオプションが新たに追加されました。 (Pull Requests 1, 2 / 詳細)render :plain
、render :html
、render :body
が追加されました。(Pull Request / 詳細)
5 Action Mailer
変更の詳細についてはChangelog を参照してください。
5.1 主な変更点
37 Signals社のmail_view gemを元にメイラーのプレビュー機能が追加されました。(Commit)
Action Mailerメッセージの生成が計測されるようになりました。メッセージを生成するのにかかった時間がログに記録されます。(Pull Request)
6 Active Record
変更の詳細についてはChangelog を参照してください。
6.1 削除されたもの
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
に設定してください。(Pull Request)
6.2 非推奨
quoted_locking_column
メソッドは非推奨です。現在使われている場所はありません。ConnectionAdapters::SchemaStatements#distinct
は内部で使われなくなったため非推奨です。(Pull Request)rake db:test:*
タスクは非推奨となりました。データベースは自動的にメンテナンスされます。railtiesのリリースノートを参照してください。(Pull Request)使われていない
ActiveRecord::Base.symbolized_base_class
、および置き換えのないActiveRecord::Base.symbolized_sti_name
は非推奨になりました。Commit
6.3 主な変更点
デフォルトのスコープは、条件を連鎖した場合にオーバーライドされなくなりました。
今回の変更より前にモデルでdefault_scope
を定義していた場合、同じフィールドで条件が連鎖している場合にはオーバーライドされていました。現在は、他のスコープと同様、マージされるようになりました。詳細
モデルの属性やメソッドから派生する便利な "pretty" URL用に
ActiveRecord::Base.to_param
が追加されました。(Pull Request)ActiveRecord::Base.no_touching
が追加されました。モデルへのタッチを無視します。(Pull Request)MysqlAdapter
およびMysql2Adapter
における型変換の真偽値が統一されました。type_cast
はtrue
の場合に1
を、false
の場合に2
を返します。(Pull Request).unscope
を指定するとdefault_scope
で指定された条件が削除されます。(Commit)ActiveRecord::QueryMethods#rewhere
が追加されました。既存の名前付きwhere条件をオーバーライドします。(Commit)ActiveRecord::Base#cache_key
が拡張され、timestamp属性のリストをオプションで取れるようになりました。timestamp属性リストのうち最大値が使われます。(Commit)enum属性を宣言する
ActiveRecord::Base#enum
が追加されました。enum属性はデータベースのintegerにマップされますが、名前でクエリできます。(Commit)json値が書き込み時に型変換されます。これにより値がデータベースからの読み出し時と一貫します。(Pull Request)
hstore値が書き込み時に型変換されます。これにより値がデータベースからの読み出し時と一致します。(Commit)
サードパーティ製ジェネレータ用に、
next_migration_number
がアクセス可能になりました。(Pull Request)引数を
nil
にしてupdate_attributes
を呼び出すと、常にArgumentError
エラーが発生します。具体的には、渡された引数がstringify_keys
に応答しない場合にエラーが発生します。(Pull Request)CollectionAssociation#first
/#last
(has_many
など) による結果の取り出しで、コレクション全体を読み出すクエリの代りに、限定的なクエリが使われるようになりました。(Pull Request)Active Recordモデルクラスの
inspect
は新しい接続を初期化しなくなりました。つまり、データベースが見つからない状態でinspect
を呼び出した場合に例外を発生しなくなりました。(Pull Request)count
のカラム制約が削除されました。SQLが無効な場合にはデータベース側でraiseされます。(Pull Request)Railsが逆関連付けを自動で検出するようになりました。関連付けで
:inverse_of
オプションを設定していない場合、Active Recordはヒューリスティックに逆関連付けを推測します。(Pull Request)ActiveRecord::Relationの属性のエイリアスを扱うようになりました。シンボルキーを使うと、ActiveRecordはエイリアス化された属性名をデータベース上の実際のカラム名に翻訳します。(Pull Request)
フィクスチャーのERBファイルはメインオブジェクトのコンテキストでは評価されなくなりました。複数のフィクスチャーで使われているヘルパーメソッドは、
ActiveRecord::FixtureSet.context_class
でインクルードされるモジュール上で定義しておく必要があります。(Pull Request)RAILS_ENVが明示的に指定されている場合はテストデータベースのcreateやdropは行いません。(Pull Request)
Relation
には#map!
や#delete_if
などのミューテーターメソッド (mutator method) が含まれなくなりました。これらのメソッドを使いたい場合は#to_a
を呼び出してArray
に変更してからにしてください。(Pull Request)
find_in_batches
、find_each
、Result#each
、Enumerable#index_by
は、自身のサイズを計算可能なEnumerator
を返すようになりました。(Pull Request)scope
、enum
とAssociationsで "dangerous" 名前衝突が発生するようになりました。(Pull Request, Pull Request)second
からfifth
メソッドはfirst
ファインダーと同様に動作します。(Pull Request)touch
がafter_commit
とafter_rollback
コールバックを発火するようになりました。(Pull Request)sqlite >= 3.8.0
でのパーシャルインデックスが有効になりました。(Pull Request)change_column_null
が復元可能になりました。(Commit)マイグレーション後無効になったスキーマダンプにフラグが追加されました。これは新しいアプリケーションのproduction環境ではデフォルトで
false
に設定されます。(Pull Request)
7 Active Model
変更の詳細についてはChangelog を参照してください。
7.1 非推奨
-
Validator#setup
は非推奨です。今後はバリデーターのコンストラクタ内で手動で行なう必要があります。(Commit)
7.2 主な変更点
ActiveModel::Dirty
に、状態を制御する新しいAPIreset_changes
およびchanges_applied
が追加されました。検証の定義時に複数のコンテキストを指定できるようになりました。(Pull Request)
attribute_changed?
がハッシュを受け付けるようになり、属性が与えられた値に
変更されたか(または与えられた値から
変更されたか)どうかをチェックするようになりました。(Pull Request)
8 Active Support
変更の詳細についてはChangelog を参照してください。
8.1 削除されたもの
MultiJSON
依存が削除されました。これにより、ActiveSupport::JSON.decode
はMultiJSON
のオプションハッシュを受け付けなくなりました。(Pull Request / 詳細)カスタムオブジェクトを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'が削除されました。(Commit)
8.2 非推奨
時間表現
Numeric#{ago,until,since,from_now}
が非推奨になりました。この値はAS::Durationに明示的に変換してください。例:5.ago
=>5.seconds.ago
(Pull Request)requireパス
active_support/core_ext/object/to_json
が非推奨になりました。active_support/core_ext/object/json
を代りにrequireしてください。(Pull Request)ActiveSupport::JSON::Encoding::CircularReferenceError
が非推奨になりました。この機能はactivesupport-json_encoder gemに書き出されました。(Pull Request / 詳細)ActiveSupport.encode_big_decimal_as_string
オプションが非推奨になりました。この機能はactivesupport-json_encoder gemに書き出されました。 (Pull Request / 詳細)カスタムの
BigDecimal
シリアライズが非推奨になりました。(Pull Request)
8.3 主な変更点
ActiveSupport
のJSONエンコーダーが書き直され、pure-RubyのカスタムエンコーディングではなくJSON gemを利用するようになりました。 (Pull Request / 詳細)JSON gemとの互換性が向上しました。 (Pull Request / 詳細)
ActiveSupport::Testing::TimeHelpers#travel
および#travel_to
が追加されました。これらのメソッドは、Time.now
およびDate.today
をスタブ化することによって、現在時刻を指定の時刻または時間に変換します。ActiveSupport::Testing::TimeHelpers#travel_back
が追加されました。このメソッドは、travel
およびtravel_to
メソッドによって追加されたスタブを削除することで、現在時刻を元の状態に戻します。(Pull Request)Numeric#in_milliseconds
が追加されました。1.hour.in_milliseconds
のように利用でき、これをgetTime()
などのJavaScript関数に渡すことができます。(Commit)Date#middle_of_day
、DateTime#middle_of_day
、Time#middle_of_day
メソッドが追加されました。エイリアスとしてmidday
、noon
、at_midday
、at_noon
、at_middle_of_day
も追加されました。(Pull Request)期間を生成するための
Date#all_week/month/quarter/year
が追加されました。(Pull Request)Time.zone.yesterday
とTime.zone.tomorrow
が追加されました。(Pull Request)よく使われる
String#gsub("pattern,'')
の省略表現としてString#remove(pattern)
が追加されました。(Commit)値がnilの項目をハッシュから削除するための
Hash#compact
およびHash#compact!
が追加されました。(Pull Request)blank?
およびpresent?
はシングルトンを返します。(Commit)新しい
I18n.enforce_available_locales
configのデフォルトはtrue
です。これは、ロケールに渡されたI18n
がavailable_locales
リストに載っていなければならないということです。(Pull Request)
Module#concerning
が導入されました。自然かつ堅苦しくない方法で、クラスから責任を分離します。(Commit)
-
Object#presence_in
が追加されました。値を単に許可済みリストに追加します。(Commit)
9 クレジット表記
膨大な時間を費やしてRailsを作り、頑丈かつ安定したフレームワークにしてくれた多くの皆様については、Railsコントリビューターの完全なリストを参照してください。これらの方々全員に敬意を表明いたします。