Upgrade Rails project from 2.3 to 3.0

曾今将一个项目代码由 Rails 2.3.11 升级为 3.0.20。整理一下在这个过程中,解决问题的清单。

升级的原因主要是 Rails 3 在性能和安全上有很大提升,另外 3 引入 assets 管理 js/css/images; 使用 bundler 管理 gems等特性都非常实用。

1. 安装 rails_upgrade

链接 这个 Gem 封装了以下四个 rake 命令:

# Check your app for required upgrades
rake rails:upgrade:check
    执行完上面的任务,会查找不兼容的语法和插件。
    最后列出一堆需要修改的文件,并给出需要修改的原因。
  
# Backup your likely modified files that might be overwritten by the generator
rake rails:upgrade:backup
    该任务用来备份重要的配置文件。
  
# Generate a new route file
rake rails:upgrade:routes
    会把 Rails 2.3 格式的 route 文件转化成 Rails 3 格式。
  
# Generate a Gemfile from your config.gem directives
rake rails:upgrade:gems
    会把写在 environment.rb 里面的 gem 管理方式变成 bundle 管理的 Gemfile 格式。
  
# Generate code for a new config/application.rb from your environment.rb
rake rails:upgrade:configuration
    会将原先在 environment.rb 里面的其他设置转化成 Rails 3 格式的 config/application.rb 文件。
  

2. 生成 Rails 3 文件

在项目目录下执行

rails new .
文件生成后,基于 Rails 3 修改项目配置信息: session, cookie等。
# Rails 3
Railsapp::Application.config.session_store :active_record_store, :key => 'your-session-key'
Railsapp::ActionController::Base.config.secret_token = 'your-secret-token'

# 项目常量写法
RAILS_ENV Rails.env
RAILS_ROOT  Rails.root

# Test helpers path
require 'rails/test_help'

# autoload path
config.autoload_paths += %W(#{Rails.root}/lib #{Rails.root}/extras)
调整 route 配置,参考文章 rails-3-router rails-3-upgrade

3. Gems/Plugins 升级

will_paginate 由 plugin 替换为 gem. 重写分页的显示需要参考: 文章链接

# .paginate().all 
cache_fu 替换为 dalli Dalli 链接

4. Helpers

# 多加 = 等号,输出 html
# form_for, form_tag, fields_for and link_to using < % = instead of < %
    
# Rails 3 默认使用了 safebuffers, 不需要到处加< % = h ... % >
# Rails 3 推荐无侵入式的JS,一些旧的 onclick 的 helper 都改写成 UJS 方式
# Use raw to avoid escaping HTML characters in views
# html_safe
# helper :all,Rails 源代码 Bug
# 重写 error_messages_for
# form_remote_for 参考改进链接:
prototype_legacy_helper

5. ActiveRecord

# validate callback 语法改变
# Change :dependent => destroy to :dependent => :destroy
# has_and_belongs_to_many
# .find(:all) to .all()

6. ActionController

# 需要显示指明 layout, 法则报错。错误原因为 Rails 源代码 Bug
# render :template=>template, :layout => "application"

2013-03-20

rocket-wing