暇人じゃない

奈々さんのライブ映像を観ながらハッカソン: Ruby 2.0.0/Rails 4.0.0 Beta 1 移行

@yonetin 宅で、水樹奈々さんのライブ映像を鑑賞しながらハッカソンをしてきました。

〜 1 日目 〜

1 日目は起きたのが遅かったのもあり、@yonetin 宅に到着したのが昼過ぎ。
手作りのカレーをご馳走してもらいました。

ちなみに、以下のライブ映像を観ました:

鑑賞して分かったことは、映像に気を取られて集中できないことです。
心地の良いソファーと、よつばと!の最新巻があったのも原因の一つでした。

そんなこんなで、いつの間にか寝ていたり、夜はラーメンを食べたり新潟の美味しい日本酒を飲みながらぐだぐだしたりで、1 日目ほとんど何もせず終わりました。
完全にダメなパターンです。

〜 2 日目 〜

2 日目は、Heroku で動かしている割とシンプルな Rails アプリを、Ruby 2.0.0-p0 、Rails 4.0.0 Beta1 に移行しました。

以下、移行する時にやったことのメモ:

Ruby 2.0

Gemfile

Ruby 2.0.0 support released | Heroku Dev Center にある通り、Gemfile に 1 行記述するだけで Ruby 2.0.0 に移行することができました。

Gemfile:

ruby "2.0.0"

テストをある程度書いていましたが、すべてパスし、ステージング環境にデプロイしてみて動作することを確認しました。

Rails 4.0.0 Beta1

※文中の Rails 3 は Rails 3.2.x、Rails 4 は移行時の最新バージョンである Rails 4.0.0 Beta 1 を指しています。

全体的に、以下の記事を参考にしました:
RubySource | Get Your App Ready for Rails 4RubySource
http://rubysource.com/get-your-app-ready-for-rails-4/

すべての Gem を最新版にアップデートする

Rails 4 とはあまり関係無いのですが、いくつかの Gem が古くなっていたのですべてアップデートしました。

Rails 4 をインストール

Gemfile に以下のように記述し、bundle update rails を実行します:

gem 'rails', "~> 4.0.0.beta1"
gem 'sass-rails', "~> 4.0.0.beta1"
gem 'coffee-rails', "~> 4.0.0.beta1"

このアプリでは sass-rails と coffee-rails が依存しているため、同時にアップデートします。
なお、今回は turbolinks や jbuilder は使用していません。

とりあえず、Rails 4 がインストールされました。

database_cleaner

database_cleaner は現状の安定版である v0.9.1 だとエラーになります。
Rails 4 に対応している v1.0.0 RC1 がリリースされているので、そちらを使用します。

gem 'database_cleaner', "~> 1.0.0.RC1"

rake rails:update

rake rails:update は、config 以下の environmentsinitializer などを、新しいバージョンのもので上書きするタスクです。
Rails 4 では、設定ファイルがだいぶ変わっているので実行しておいた方が良いでしょう。

ファイルがコンフリクトする場合は、上書きするかそのままにするか、diff を見るかなどを選択することができます。
今回のアプリの場合は、ほとんど手を入れていなかったのであまり手間取ることはありませんでした。何らかの変更を加えている場合は、diff を見ながら設定を反映していきましょう。

autoload_path

Rails 4 から、デフォルトで config/libautoload_paths に設定されていると聞いていたのですが、デフォルトでは読み込まれませんでした。 Rails 3 と同じく autoload_paths に lib ディレクトリを追加しました。僕の勘違いな気がします。

config/application.rb:

config.autoload_paths += Dir["#{config.root}/lib"]

strong_parameters

アプリ側の修正は主に Strong Parameters への対応でした。

モデルで attr_accessible を記述している部分を削除し、コントローラー側で Strong Parameters の設定を行います。

app/controllers/photos_controller.php:

def create
  @photo = Photo.new(photos_params)
  ...
end

private

def photos_params
  params.require(:photo).permit(:title)
end

ActiveRecord Scope

Active Recode の scope は Proc や lambda で書いてあげる必要があります。

app/models/photo.rb:

# 元々はこんな感じ:
# scope :new_uploads, order("id DESC")
scope :new_uploads, -> { order("id DESC") }

guard + spork -> guard + spring

Rspec 単体でテストを流す分には問題なく動くようになったのですが、guard-spork にて Active Resource がなんちゃらと、Rails 3 周りに依存しているようなエラーが出るので、最近よく耳にする spring に乗り換えました。

spring に似ているものに command や zeus がありますが、もうすぐ春なので…(?)

この辺りを参考にしました。

Faster Rails specs with spring - faster than spork and easier to setup - Stefan Wienert - Blog
http://stefanwienert.net/blog/2013/02/08/faster-rails-tests-with-spring-faster-than-spork-und-easier-to-setup/

Heroku で Asset Pipeline

ローカルで確認したし Heroku にデプロイして完了!というところまできたのですが、実際にページをみてみると CSS と JS が 404 Not Found になっていました。assets:precompile では特にエラーは吐かれていません。

これは serve_static_assets を有効にしていないのが原因でした。

config/environments/production.rb:

config.serve_static_assets = true

本来であれば Apache や nginx が静的ファイルの配信を行いますが、Heroku ではアプリケーションサーバーに配信してもらう必要があります。

また、Rails 3 では config.assets.initialize_on_precompilefalse にしろ、との記述がありますが、Rails 4 では設定する必要はなくなりました。

どちらの件も Heroku のドキュメントに記載があります。

Rails Asset Pipeline on Heroku Cedar | Heroku Dev Center
https://devcenter.heroku.com/articles/rails-asset-pipeline#assetsprecompile-failures

だいたい良さそう

だいたい動くことを確認できたので、これで一旦完了としました。

ちなみに、この Rails アプリは Ochiba というシンプルなフォトブログです。
実装が汚い部分はありますが、アップデート周りで参考になる部分があったら参考にしてみてください。

しばらくは Rails 3 のままで、と思っていましたが、Rails 2 と同じように、いつかは Rails 4 に移行する必要があります。
移行時の辛さはありますが、放っておいても、長期的に見て良いことは無いと思います。

正式版がリリースされたら、他のアプリも早めに移行しようと思います。
まずは Ruby 1.9.3 から Ruby 2.0.0 への移行をやってみると良いのではないのでしょうか。

終わりに

結局、2 日目は奈々さんのライブは観ませんでした。
普通に曲を流すぐらいがちょうど良さそうですね。

またやりたいと思います。