Rails5 の落とし穴

Rails 5 がリリースされましたね。いつものことですが、Rails のリリースノートは『新機能最高!!!』って見せながらサラッと落とし穴を用意してくるあたり、実に渋いなと思います。本当にやめて欲しい。

大体 Upgrading from Rails 4.2 to Rails 5.0 な内容ではあるので、不正確な情報を頼りにするよりはできれば本家の Rails Guide を当たるほうがオススメです。

ということで、発見した落とし穴を随時更新していこうかと思います。なお、移行元は Rails 4 を想定していますので、 Rails (バージョンを問わない)特有の落とし穴については各自やっていく気持ちで対処して下さい。

belongs_tooptional オプションが追加されました

(ついでに required オプションが非推奨になりました)

一発目から戦争勃発という感じですが、 belongs_tooptional オプションというのが追加されました。

いままでも required というオプションは存在し、有効にしていると validates :model, presence: true と同等の効果があったのですが、今回 optional の追加により更に激しく デフォルトで false なので belongs_to :model と書くと、特に何もしてなくても validates :model, presence: true されている状態になります。

激しい、激しすぎる、すごい、つよい、マジかよ。

なお、このデフォルトの挙動は config/initializers/new_framework_defaults.rb にある Rails.application.config.active_record.belongs_to_required_by_default = truefalse にすれば Rails4 と同様の挙動になります。

一応、既存のアプリケーションでは後方互換性のために belongs_to_required_by_default はデフォルトで false になっています。新規に rails new した時しか踏み抜かないはずです。

新規はいっちょ Rails5 でいくか!という時に踏み抜く落とし穴です。ご注意下さい。

ref:

この落とし穴を解明した時の気持ち

嘘だろ

コールバックで false を返しても止まらなくなりました(コールバックチェインが継続します)

まぁ見出しの通りなんですが、コールバック(before_* とか)を次のコールバックに行かせずに返す場合、 false を返せばよかったのですが、今後は throw(:abort) でコールバックチェインを止める仕様になりました。

こちらも config/initializers/new_framework_defaults.rb にある ActiveSupport.halt_callback_chains_on_return_false = falsetrue に変えれば Rails4 と同様の動作になります。

戻り値を見なくなって例外で抜けるの、ちょっともにょるんだけど仕方ないのかな……

ref:

この落とし穴を解明した時の気持ち

うーん、まぁ、大域脱出的では、まぁ、あるし……いやぁでも……

ActiveSupport::TestCase のテスト実行順序がデフォルトランダムになりました

個人的には元から random で実行して欲しかったのでどっちでもいいっちゃどっちでもいい変更ですが、気にせずシーケンシャル実行前提のテストを書いているとハマると思います。

解決方法は config/environments/test.rbconfig.active_support.test_order = :sorted と書き足しましょう。

でも、できればテストは1テスト毎に独立してたほうが望ましいと僕は思うので、 :random でもやっていけるようにテストを考えなおしてみるのもいいんじゃないかな、と思います。

なお、コレに限っては Rails5 にすると自動で有効です。気をつけて下さい。

ref:

この落とし穴を解明した時の気持ち

いいね!

まだ見つけてない他の落とし穴

見つけたらここに書き足しておきますね