暇人じゃない

CurryBu を Rails 4 にアップデートしてハマったところ

遅くなりましたが、Rails 4.0.0 の正式版がリリースされましたね! CurryBu については諸々の環境(主に gem ですが…)が落ち着いてきてから Rails 4 にアップデートしようと思っていました。

しかし、CurryBu は元々 Rails の勉強で始めたということや、以前、小さめのアプリを Rails 3.2.x から Rails 4.0.0.beta.1 にアップデートした こともあったので、Rails 4 にアップデートすることにしました。

今回のアップデートでハマったところを書いてみます。 2013/07/12 にアップデートを行ったときの情報ですので注意してください。

Gem まわり

最新の情報については各 Gem の GitHub を参照することをおすすめします。

devise

https://github.com/plataformatec/devise

アップデートしたときは Rails 4 / Strong Parameters に対応した 3.0.0.rc がリリースされていました。2013/07/15 現在、正式版の 3.0.0 がリリースされています。3.0.0 でも動作を確認しました。

Devise の Strong Parameters については以下のような感じで対応するようになりました:

class ApplicationController < ActionController::Base
  before_filter :configure_permitted_parameters, if: :devise_controller?

  private

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:login_name, :password, :password_confirmation)
    end
  end
end

詳しくは README の Strong Parameters の項目を参照してください:
https://github.com/plataformatec/devise#strong-parameters

friendly_id

https://github.com/FriendlyId/friendly_id

friendly_id は Rails 4 に対応した Gem がリリースされていないため、GitHub の master ブランチを参照することになります。バージョン情報を見る感じでは、Rails 4 に対応したバージョンは 5.0.0 になりそうです。

gem 'friendly_id', github: 'FriendlyId/friendly_id', branch: 'master'

master ブランチに新しいコミットがあった場合、bundle update する度にアップデートされるので、指定したコミット ID でアップデートを行いたい場合は ref でコミット ID を指定しても良いかもしれません。僕はこちらの方にしています。

gem 'friendly_id', github: 'FriendlyId/friendly_id', ref: 'a25368945623c14798920e3316117bc5bd359e10'

また、friendly_id の API が変更になり、friendly というスコープを通して find メソッドにパラメーターを渡すようになりました。具体的に言うと、以下のような書き方をするようになりました。個人的には新しい方が安心感というかシンプルさがあって好きです。

# old
User.find('john')

# new
User.friendly.find('john')

paranoia

https://github.com/radar/paranoia

論理削除には actsasparanoid を使用していたのですが、Rails 4 に対応するための Pull Request は来ているがアップデートされる気配がない/実装を見るとなんだかゴチャゴチャしている、という点が気になっていたため、Rails 4 に対応しており、コードの見通しが良い paranoia に乗り換えました。

gem "paranoia", "~> 2.0.0"

paranoia は actsasparanoid 互換の API になっているため、コードの書き換えはゼロで済みました。

format バリデーターの正規表現

format バリデーターで以下のような指定をしていると、エラーが出るようになりました。

モデル:

validates :hoge,
  format: { with: /^[0-9A-Za-z_-]+$/ }

エラー:

/-/.bundle/ruby/2.0.0/gems/activemodel-4.0.0/lib/active_model/validations/format.rb:46:in `check_options_validity': 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? (ArgumentError)

^$ は複数行にマッチするため、脆弱性になってしまう可能性があるということで、multiline オプションを指定するか、^\A に、$\z に置き換えましょう、ということらしいです。以下のように書き換えました。

validates :hoge,
  format: { with: /\A[0-9A-Za-z_-]+\z/ }

^ は行の先頭 / $ は行の末尾、\A は文字列の先頭/ \z は文字列の末尾にマッチする、という違いがあるみたいです。ややこしい。いつも ^/$ を使っていたので、今後は使い分けていきたいです。

time_ago_in_wordsinclude_seconds

timeagoin_words は時間を渡すと「〜分前」を返してくれるメソッドなのですが、以前は第 2 引数に true を渡すと「〜秒前」と秒単位で返してくれていました。しかし、第 2 引数に boolean を渡すのは非推奨になったようで、オプションを渡すようになったようです。

time_ago_in_words(Time.now, include_seconds: true)

Guard + Spring

以前のエントリでも書きましたが Guard + Spork から Guard + Spring に乗り換えました。

Ruby 2.0.0

CurryBu の Ruby は Ruby 2.0.0-p247 にアップデート済みです。1.9.3 を使用しているのであれば、ほとんど問題は起きないはずなので、まずは Ruby のアップデートから始めてみると良いのではないでしょうか。

まとめ

テストを書くようにしていることもあり、割と楽だったかなという印象があります。これが大規模アプリだったら大変なのかもしれません。

Rails 4 にアップデートが終わったので、「アップデートしなければ!」と気にせず開発に集中できるようになりました。いずれは Rails 4 に移行しなければいけませんし、早めにアップデートした方が良いですね。

また、サーバー起動時にエラーが出るものが多いので、早めに気がつけて助かります。

皆さんのお役に立てれば幸いです。