読者です 読者をやめる 読者になる 読者になる

彼女からは、おいちゃんと呼ばれています

ウェブ技術や日々考えたことなどを綴っていきます

Rails 4 へ移行してあらためて大切だと思ったこと + 役に立ったリンクを全力まとめ

先週 babyshark を Rails 3.2.13 から Rails 4.0.0 にアップデートしました。巷の情報では

StrongParameters さえ気をつけておけば、なんとかなる

的な。いやいや、たしかに Rails 2.3 -> 3.0 ほどの大変さではないにしろ、結構大変でしたよ。嘗めてかかるとエライ目に遭うと思います。

というわけで、移行してみて改めて大切だと思ったことと、ハマったポイントを共有します。久しぶりの長文。全力でいきますよ。

Rails 4 へ移行してあらためて大切だと思ったこと + 役に立ったリンクを全力まとめ

  • 1. Rails 3.2 との変更点を把握しておく
  • 2. 使っている gem が Rails 4 に対応しているか確認する
  • 3. 事前に Rails 3.2 の最新バージョンまで上げておく
  • 4. gem もできるだけ最新バージョンにしておく
  • 5. テストを書いておく
  • 6. 移行を手助けしてくれる gem を把握しておく
  • 7. 移行するか新しくつくり直すか検討する
  • 8. 設定ファイルの差分を把握しておく
  • 9. ハマりどころまとめ
    • (1) バリデータの正規表現
    • (2) Sweeper が使えなくなった
    • (3) jQuery の live が効かなくなった
    • (4) rake test:prepare できない
    • (5) Capybara さんがぁあああ
    • (6) Bootstrap のデザインが崩れた
    • (7) Capistrano からデプロイできない
    • (8) その他
  • 10. DEPRECATION WARNING の駆逐
    • (1) 名前付きスコープを lambda 記法にする
    • (2) will_paginate の order 指定
  • 参考書籍

1. Rails 3.2 との変更点を把握しておく

これはもう、当たり前ですけども。把握しないでバージョン上げちゃうのは自殺行為です。

細かい点を含めると結構変更点があるので、どんな変更点があるのか事前に把握しておくの必須です。WEB+DB PRESS vol.73 に「詳解 Rails4」という特集が載っているので、それに目を通すのがきっと一番良い方法です。

WEB+DB PRESS Vol.73

WEB+DB PRESS Vol.73

  • 作者: 設樂洋爾,白土慧,はまちや2,大和田純,松田明,後藤大輔,ひろせまさあき,小林篤,近藤宇智朗,まかまか般若波羅蜜,Mr. O,川添貴生,重国和宏,柳澤建太郎,奥野幹也,佐藤鉄平,後藤秀宣,mala,中島聡,堤智代,森田創,A-Listers,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/02/23
  • メディア: 大型本
  • 購入: 12人 クリック: 131回
  • この商品を含むブログ (7件) を見る

どうしてもウェブ情報が良い(だって無料だし)という人は、下記リンクあたりかなー

いやー、でもやっぱり、WEB+DB PRESS のほうを推したいなー。36ページにもわたって、詳しく分かりやすく書かれていますので。

2. 使っている gem が Rails 4 に対応しているか確認する

大事。Rails 4 に上げた後に動かないことに気づいたら、進むも地獄、戻るも地獄です。。

それ専用のサイトがあったのですが、まだまだ情報が出揃っていない感じがありますね。。

人柱さんに感謝しましょう。

ちなみに babyshark では、検索機能にお手軽な MetaSearch(meta_search)を使っていたのですが、現時点で Rails 4 に対応しておらず、かつ開発も止まっているようなので、後継らしい Ransack に乗り換えました。

3. 事前に Rails 3.2 の最新バージョンまで上げておく

いま現在 Rails 3.2 の最新バージョンが 3.2.14。できるだけ最新のバージョンから移行させた方が無駄にハマらなくて済むと思います。

4. gem もできるだけ最新バージョンにしておく

あと、後述しますが、今回 僕がハマったのは、Rails 4 そのものよりも移行に伴う、周辺 gem のアップデートに起因する点が多いです。使っている gem も、移行前にできるだけ最新のものにしておいた方が良いでしょう。

特に Capybara は、バージョン上げたらテストこけるとか結構あるので、事前に上げて潰しておいた方が(ゼッタイに)良いです。

5. テストを書いておく

テストを書かなくても許されるのは(ry

事前にいろいろ準備しておいても、Rails 4 に上げた直後は、テストが盛大にこけます。が、それはテストを書いていればこそ気づける修正箇所なので、テストはきちんと書いておきましょう。ね。

6. 移行を手助けしてくれる gem を把握しておく

移行を手助けしてくれる gem を大別すると、次の 2つがあります。

  • (1) Rails 4 の機能を Rails 3.2 でも使えるようにするもの
  • (2) Rails 4 で本体から切り捨てられた機能を Rails 4 でも使えるようにするもの

(1) のタイプとしては、例えば Rails 3.2 で StrongParameters を使えるようにする strong_parameters とか。

(2) のタイプとしては、Rails 4 で attr_accessible を使えるようにする protected_attributes とか。同じく Rails 4 で sweeper(opserver)を使えるようにする rails-observers とか。他にもキャッシュ関係、セッション、いろいろ。

下記が詳しいです。

Rails 4 の変更点を把握した上で、上記の gem との付き合い方を決めておく。

個人的には、移行をできるだけスムーズに行うために、積極的に (1) のタイプの gem を利用するのが賢明かなと思います。あと、いずれ書き換えるつもりでかつ移行前に書き換え可能なものは、移行前に書き換えてしまう。

また、後述しますが、移行直後、まずは最短で動くようにして、テストを通したかったので、(2) のタイプの gem にもお世話になりました。

7. 移行するか新しくつくり直すか検討する

みんな大好き「Rails チュートリアル」には、Rails 3.2 からの「移行」ではなくて、Rails 4 でアプリケーションを「新規につくって、そこに Rails 3.2 のファイルを移していく」方法が推奨されています。

一見回り道に感じますが、アプリケーションの規模が小さいときは、こちらのやり方のほうが近道かもしれません。

ちなみに僕の場合は、移行、つまり rake rails:update する方法を選びました。どちらのやり方のほうが早かったのかは微妙なところですが、新規にアプリケーションをつくるとなると Git のログが激しいことになりそうだったので避けたという感じです。

8. 設定ファイルの差分を把握しておく

上記 7. のうち、「新規作成」ではなく「移行」する方法をとる場合には、バージョン間の設定ファイルの差分を把握しておくと何かと捗ります。

他のプロジェクトのプルリクエスト差分も参考になりました。

9. ハマりどころまとめ

さて、移行に伴うハマりどころについて、先人のありがたい情報をまとめます。リンクが見つからないものは自前で書きます。

(1) バリデータの正規表現

Rails 4 からバリデータの正規表現が厳しくなりました。複数行の文字列に対して ^ とか $ を使っていたらエラーが出ます。詳細は下記リンク参照。

The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?

(2) Sweeper が使えなくなった

Sweeper を利用してキャッシュの削除を行っていましたが、エラーが出ました。

undefined method `cache_sweeper' for VideosController:Class

まだ継続して使いたいので、rails-observers を入れました。

(3) jQuery の live が効かなくなった

Rails 4 へのアップデートとともに、jQuery のバージョンも上がるので、例えば live とか、動かなくなるメソッドを書き換える必要があります。

(4) rake test:prepare できない

Rails 3.2 のときは rake db:test:prepare ってしてましたが、Rails 4 からは rake test:prepare というコマンドになりました(前のコマンドも使える)。が、下記のエラーでこけました。

cannot load such file -- zip/zip

rubyzip の 0.9.9 を入れて解決。1.0.0 だとダメでした。

gem 'rubyzip', '0.9.9'

(5) Capybara さんがぁあああ

今回の移行により capybara のバージョンを上げました(1.1.4 -> 2.1.0)。そうしたら、テストがこけるこける。。Rails になくてはならない神 gem のひとつですが、バージョンアップのたびに泣かされる人続出ですね。。

そういえば、過去に一度 2.0 に上げようとして、これ無理ゲーだわと思って戻したのを思い出しました。2.1 になって、いろいろとオプションで挙動を変えられるようになったようです。

英語が無理ゲーな人は下記参照。内容はだいたい同じっす。

書き方の変更とか。

- it { expect(subject).to have_selector('title', text: "AV女優一覧 - #{I18n.t('site_name')}") }
+ it { expect(subject).to have_title("AV女優一覧 - #{I18n.t('site_name')}") } 

オプションの変更。下記は meta タグのテストのために書いたものです。

+ Capybara.ignore_hidden_elements = false

(6) Bootstrap のデザインが崩れた

おそらく Rails 4 関係ないですけど。移行に伴い Bootstrap 関係のバージョンが上がって、一部のデザインが崩れました。何が言いたいかというと、場合によっては、移行作業にデザイナのサポートも必要だということです。

- bootstrap-sass (2.0.4.0)
+ bootstrap-sass (2.3.2.0)
- bootstrap-will_paginate (0.0.6)
+ bootstrap-will_paginate (0.0.9)
- bootswatch-rails (0.0.12)
+ bootswatch-rails (0.5.0) 

(7) Capistrano からデプロイできない

移行に伴い Capistrano 2.15.5 に上げてデプロイしようとしたら、こけました。

僕の場合は、正常に動いていた 2.15.0 までバージョンを下げて対処しましたが、公式に対処方法が書かれていました。manifest.yml を手動でコピーしてあげるとか。

(8) その他

再掲になりますが、やはりこのあたりの必ず目を通しておいた方が良いかも。定番ぽい。

devise, friendly_id, acts_as_paranoid -> paranoia, format バリデータの正規表現ほか。今回僕は遭遇しませんでしたが、ログイン周りでこけたら恐怖ですね。

multi_db 等 MySQL まわり。このあたりもハマりたくないなー。

10. DEPRECATION WARNING の駆逐

まあ、急いでやる必要はないのかもしれませんが、気持ちとして、早くスッキリしたいですしね。。

(1) 名前付きスコープを lambda 記法にする

EPRECATION WARNING: Using #scope without passing a callable object is deprecated. For example `scope :red, where(color: 'red')` should be changed to `scope :red, -> { where(color: 'red') }`. There are numerous gotchas in the former usage and it makes the implementation more complicated and buggy. (If you prefer, you can just define a class method named `self.red`.). (called from ...

下記のような感じで書き換えます。

- scope :available, where(status: Settings.tag.status.available) 
+ scope :available, -> { where(status: Settings.video.status.available) } 

(2) will_paginate の order 指定

DEPRECATION WARNING: #apply_finder_options is deprecated.

will_paginate の order 指定は、paginate メソッドの外に出します。

@videos = Video.available.
-        paginate(page:     params[:page],
-                 order:    order_text(params[:order]),
-                 per_page: per_page).
+        order(order_text(params[:order])).
+        paginate(
+          page: params[:page],
+          per_page: per_page)

以上です。最後までお付き合いいただきありがとうございました。みなさまにおかれましては、無事に移行できますように!

参考書籍

いろいろ書いたけど、やっぱり Rails 4 の良いところを正しく使うには、下記は必読だと思います。

WEB+DB PRESS Vol.73

WEB+DB PRESS Vol.73

  • 作者: 設樂洋爾,白土慧,はまちや2,大和田純,松田明,後藤大輔,ひろせまさあき,小林篤,近藤宇智朗,まかまか般若波羅蜜,Mr. O,川添貴生,重国和宏,柳澤建太郎,奥野幹也,佐藤鉄平,後藤秀宣,mala,中島聡,堤智代,森田創,A-Listers,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/02/23
  • メディア: 大型本
  • 購入: 12人 クリック: 131回
  • この商品を含むブログ (7件) を見る