Rails3.1.0へのupgrade方法

#282 Upgrading to Rails 3.1 - RailsCastsを見て、


The Ruby Toolbox SearchをRails3.1.0に移行してみましたが、
(諸問題があり未デプロイ http://www.toolboxsearch.tk/ こっちに移行してデプロイしてます )
思ったより大変でした。
いろいろ嵌ったので、個人的にはRail2.3からRail3.0への移行よりしんどい印象です。
productionでの確認は要実施です。


あと、asset pipelineは、多分はまると思うので
Ruby on Rails Guides: Asset Pipelineを一読するのが
よいかと思います。


準備

1.「3.0系」の最新(3.0.10)へupgrade

1)Gemfile内のrailsのversionをあげる
2)bundle update rails
3)bundle exec rake rails:update
4)rails g jquery:install
5)bundle exec rake db:migrate
6)テストが通ることを確認 rake spec

upgrade

2.ブランチをきる

まずは作業用ブランチを切ります。

git checkout -b rails31 
3.Gemfile修正

1)Gemfile内のrailsのversionをあげる
gem 'rails', '3.1.0'
2)bundle update

4.development.rbを修正

コメントアウト。

  # config.action_view.debug_rjs             = true
5.テストが通ることを確認

rake spec

各種設定ファイルを修正

6.Gemfileに追加 & bundle
# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails', "  ~> 3.1.0"
  gem 'coffee-rails', "~> 3.1.0"
  gem 'uglifier'
end
bundle
7.config/application.rb その1

#before

# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)

#after

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require *Rails.groups(:assets => %w(development test))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end
8.config/application.rb その2

追加

# ...

    # Enable the asset pipeline
    config.assets.enabled = true

    # Version of your assets, change this if you want to expire all your assets
    config.assets.version = '1.0'
9.config/environments以下をそれぞれ追加

#development.rb

# 4でコメントアウトしています
# config.action_view.debug_rjs             = true

# Do not compress assets
config.assets.compress = false

# Expands the lines which load the assets
config.assets.debug = true

#test.rb
動画の中では最終行が有効になっていましたが、コメントアウトしとくのが吉だそうです。

# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"

# This config option was shown in the episode but is actually not used, so don't bother adding it.
# config.assets.allow_debugging = true

#production.rb
ここは、はまった箇所があるので補足で別途説明します。

  # Don't fallback to assets pipeline if a precompiled asset is missed
  config.assets.compile = false

  # Generate digests for assets URLs
  config.assets.digest = true
10..gitignoreに追加

.sass-cache/


11.app/assets

1)app/assetsディレクトリを追加


2)publicからassetsへ移動
public/images、javascripts、stylesheets
をapp/assetsへ移動。


3)不要なjsを削除
app/assets/javasctipts内の
jquery.js、jquery.min.js、rails.js
を削除

12.application.js

行頭に追加。

//= require jquery
//= require jquery_ujs
//= require_self
//= require_tree .
13.application.css

行頭に追加。

/*
*= require_self
*= require_tree .
*/
14.applicatoin.html.erb

asset pipelineの対象となっているjsやcssを読み込まないようにする。
applicationのみ読み込めばok。

  <%= stylesheet_link_tag 'application' %>
  <%= javascript_include_tag 'application' %>
15.画像のパスを変更

assets配下となるように修正。
image_tagを使っているところは変更不要。
cssなどで指定している場合はasset_path、asset_data_uriで設定します。(assets/path_to_image.ext でも可)
Ruby on Rails Guides: Asset Pipeline参照。



その他

はまったとこや、気になったとこ。

config.paths

config.paths.app.controller が deprecated
config.paths["app/controller"]に修正するようにとログに出ました。

#before
config.logger = Logger.new(config.paths.log.first)
#after
config.logger = Logger.new(config.paths['log'].first)
mysql2
ArgumentError: wrong number of arguments (3 for 2) 
[http://rorguide.blogspot.com/2011/09/getting-error-argumenterror-wrong.html:title=RoR Guide & Solutions: Getting error "ArgumentError: wrong number of arguments (3 for 2)" for mysql2_adapter]

mysql2のバージョンが低いのが原因でした。
gem 'mysql2', '>= 0.3'
で解決。

jsの文字コードがutf8じゃないとおこられる
FATAL -- : 
ActionView::Template::Error (/Users/rochefort/work/rails/toolbox_search/app/assets/javascripts/highcharts.js has a invalid UTF-8 byte sequence):

highchart.jsのコメント行にutf-8でない文字列が入っているのが原因でした。
削除して解決。

capistranoでエラー

2011-09-12 - @yuumi3のお仕事日記
解決方法が示されていました。ありがとうございます。

#config/deploy.rbに追記
set :normalize_asset_timestamps, false 
capistranoでbundle install

ついでに補足。
CapistranoとBundlerの連携 - Develop with pleasure!

#config/deploy.rbに追記。
require "bundler/capistrano"
capistranoでprecompile

さらに補足。

#from Rails guide
Capistrano (v2.8.0) has a recipe to handle this in deployment. Add the following line to Capfile+:

capistranoでrake assets:precompile するためのおまじないです。
Capfileに追記。

load 'deploy/assets'
precompiledエラー
[2011-09-14 15:35:22.301167 #19093]  INFO -- : Completed 500 Internal Server Error in 442ms
[2011-09-14 15:35:22.319509 #19093] FATAL -- : 
ActionView::Template::Error (base.css isn't precompiled):


application.cssでなくbase.cssという名前に変えていたのが原因でした。
production.rbに追記で解決。

config.assets.precompile += ['base.css']
productionで画像が参照できない

developmentではうまくいきますが、productionではなぜかうまくいきませんでした。
どうやらasset pipeline周りが怪しい。
rake assets:precompile 後に生成されたpubic/assets以下の画像が読めていないようでした。
正しく理解できてませんが、config.serve_static_assets をtrueにすることで
precompileしたものを参照するようになりました。

# config.serve_static_assets = false
config.serve_static_assets = true
実行環境にnodejs jsのランタイムが必要

linodeにubuntu8で実行していたのですが
precompile時にエラーとなりました。

Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes.

これってそもそもどうなの?という感じがしますが
まぁ、今時のサーバーなら、入ってて当然やろってことなんでしょうか。


ubuntuの新しいやつだと割と簡単に入れれそうなんですが
ver.8だと面倒だったので、これを機に新環境を構築している最中です。
なので、rails3.1.0の移行はとりあえずできましたがデプロイできてません。。。


20110918追記:コメントいただいたように

gem 'execjs'
gem 'therubyracer'

Gemfileに追記&bundle installでOKなようです。
(試せてませんが)


他のruntimeも下記に記載されています。
execjs


RAILS_ROOTが使えない(20110925追加)
config/initializers/00_load_config.rb:1:in `<top (required)>': uninitialized constant RAILS_ROOT (NameError)

Rails.root.to_s に変更して解決。