一个rails2.3+ruby1.8项目升级到rails3.2+ruby1.9的记录

经过2个星期的折腾,终于将一个项目从rails2.3+ruby1.8升级到rails3.2+ruby1.9,记录一下过程和踩到的地雷:升级流程:1. 在ruby1.8和rails2.3的环境下,在项目下安装rails_upgrade插件: https://github.com/rails/rails_upgrade 运行下列命令,将输出的内容保存供后续使用。 A. rake rails:upgrade:check, 它会查找不兼容的语法和插件 B. rake rails:upgrade:routes, 会把rails2.3格式的route文件转化成rails3格式 C. rake rails:upgrade:gems, 会把写在environment.rb里面的gem管理方式变成bundle管理的Gemfile格式 D. rake rails:upgrade:configuration, 会将原先在environment.rb里面的其他设置转化成rails3格式的config/application.rb文件2. 用rvm切换到ruby 1.9.3, gem install rails v=3.2 A. 执行rails new old_app_path 会提醒你是否要覆盖一些文件(比如routes.rb等),可以选择全部覆盖(做好备份) B. 将1.B生成的内容,覆盖到routes.rb C. 将1.C生成的内容,覆盖到Gemfile D. 将1.D生成的内容,覆盖到application.rb E. 执行bundle install,安装必要的gem3. 根据1.A的结果,升级插件和改必要的语法,如下几个基本上都是可以全局查找替换的: A. 插件升级,rails2的大部分插件到了3以后基本上就不能用了,比如searchlogic,可用meta_search来替代,比如cache-money,可用record-cache替代 B. 支持block的helper改变,比如form_for等支持block的helper,现在必须多个等号,改成‘<%= form_for’才能输出html C. RAILS_ROOT, RAILS_ENV等常量写法,被Rails.root, Rails.env等模块方法取代 ( http://quaran.to/blog/2010/02/03/the-rails-module/ ) D. named_scope 改成了 scope ( https://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914 ) E. 邮件发送api改变 ( http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3 )4. 下面是几个比较折腾和change log里面不太注意的地方: A. Rails 3默认使用了safebuffers: http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/这样就可以不需要到处加<%= h … %>,非常安全也非常方便,但是rails 2的项目中很多view和helper都需要改写,一些不需要escape的代码还要特别注意加上html_safe (比如richeditor的输出结果) B. ActiveRecord callback的语法改变,rails2我们可以在model里面写

class User  def after_save    self.xxx  endend

现在必须改成block方式:

class User  before_save do |user|    user.xxx  endend

C. rails_upgrade插件自动生成的routes.rb大部分能够自动工作,但是还是有发现一些namespace的route,自动生成的会出错,需要手工处理一下,改写一下。 D. class_inheritable_accessor 方法改成了 class_attribute E. request.request_uri 方法改成了 request.fullpath F. rails3推荐无侵入式的JS,一些旧的onclick的helper都改写成ujs方式 G. yaml的array格式改变(这个好像是ruby1.9的改变),原先可以写 day_names: [星期一,星期二…]现在改成了day_names – 星期一 – 星期二 H. ruby 1.9要求每个含有utf8字符的rb文件,必须在文件第一行有magic comment: # -*- encoding : utf-8 -*- 我觉的这个很折腾,为什么不是默认unicode呢?5. 4里面的麻烦还算好,基本上耐心改写,测试都可以搞定,这个项目升级遇到最大的麻烦是ruby 1.9 String encoding + yaml序列化的改变,1.8的String对象是不带encoding属性的,serialize一个属性,如果有中文的话,会当作binary存入数据库。

class Product  serialize :properties, Hashend

升级以后,必须用db migration,将数据库里面所有的数据进行force_encoding,然后再保存:

  def up    rename_column :products, :properties, :old_properties    add_column :products, :properties, :text        Product.reset_column_information    Product.find(:all).each{|p|      if pro = p.old_properties        pro.each {|k, v|          pro[k] = v.force_encoding('UTF-8') if v.is_a? String        }        p.properties = pro        p.save!      end    }  end

也许不是自己该去发挥的地方,还是让自己到最适合自己战斗的方面去吧!勇敢的接受自己的失败,

一个rails2.3+ruby1.8项目升级到rails3.2+ruby1.9的记录

相关文章:

你感兴趣的文章:

标签云: