一个rails2.3+ruby1.8项目升级到rails3.2+ruby1.9的记录_Ruby_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > Ruby > 一个rails2.3+ruby1.8项目升级到rails3.2+ruby1.9的记录

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

 2012/3/13 15:27:43  QuakeWang  程序员俱乐部  我要评论(0)
  • 摘要:经过2个星期的折腾,终于将一个项目从rails2.3+ruby1.8升级到rails3.2+ruby1.9,记录一下过程和踩到的地雷:升级流程:1.在ruby1.8和rails2.3的环境下,在项目下安装rails_upgrade插件:https://github.com/rails/rails_upgrade运行下列命令,将输出的内容保存供后续使用。A.rakerails:upgrade:check,它会查找不兼容的语法和插件B.rakerails:upgrade:routes
  • 标签:rails Ruby rails3 一个 项目
经过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,安装必要的gem


3. 根据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
  end
end


  现在必须改成block方式:
class User
  before_save do |user|
    user.xxx
  end
end


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, Hash
end

升级以后,必须用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
发表评论
用户名: 匿名