天天看點

rails2 更新到 rails3 過程詳細記錄

■為什麼寫這篇文章

rails2更新到rails3的中文資料很少,rails架構的變動卻很大,我知道更新過程的痛苦,寫這篇文章是為了減輕後來人的痛苦。

■作業要求

Ruby 1.8.7 -> Ruby 1.9.3

Rails 2.3.16  -> Rails 3.2.13

■DB環境

mysql5

■更新過程

1.請了解以下内容

Rails3 Beta版重點導覽(http://ihower.tw/blog/archives/3653)

Rails3 RC版重點導覽(http://ihower.tw/blog/archives/4590)

Rails 3.1 RC版重點導覽(http://ihower.tw/blog/archives/5611)

環境設定與Bundler(http://ihower.tw/rails3/environments-and-bundler.html)

Routing 路由(http://ihower.tw/rails3/routing.html)

Assets與Ajax(http://ihower.tw/rails3/assets-and-ajax.html)

2.安裝ruby1.9、rails3環境,建立rails3工程,将rails2代碼放到rails3工程中。

這一步主要保證rails2代碼放到rails3環境中可以正常啟動,怎樣能正常啟動呢?

①確定rails本身架構級代碼修改正确(新增config/application.rb、變更config/routes.rb等)

使用rails_upgrade更新插件(https://github.com/rails/rails_upgrade)可以比較輕松完成這一步.

rails_upgrade指令:

rake rails:upgrade:check指令會找出rails2->rails3.0所有需要更新的代碼及修改方法

rake rails:upgrade:routes指令會産生rails3用route檔案(config/routes.rb)

rake rails:upgrade:configuration指令産生rails3用config檔案(config/application.rb)

rake rails:upgrade:gems指令産生rails3用gem管理檔案(Gemfile)

rails_upgrade運作結果例

# rake rails:upgrade:check


/rake rails:upgrade:check結果開始/
Old router API
The router API has totally changed.
More information: http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/

The culprits:
        - config/routes.rb

New file needed: config/application.rb
You need to add a config/application.rb.
More information: http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade

The culprits:
        - config/application.rb


named_scope is now just scope
The named_scope method has been renamed to just scope.
More information: http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914

The culprits:
        - app/models/xxx1.rb
        - app/models/xxx2.rb

... ...

/rake rails:upgrade:check結果結束/



# rake rails:upgrade:routes

/rake rails:upgrade:routes結果開始/

xxx::Application.routes.draw do
  match '' => 'default#index'
  match 'xxx1' => 'default#login', :id => 'xxx1'
  match 'xxx2' => 'default#login', :id => 'xxx2'
  match '/:controller(/:action(/:id))'
  match ':controller/:action/:id/:id2' => '#index'
  match ':controller/:action/:id/:id2/:id3' => '#index'
end
/rake rails:upgrade:routes結果結束/



# rake rails:upgrade:configuration
/rake rails:upgrade:configuration結果開始/
# Put this in config/application.rb
require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(:default, Rails.env) if defined?(Bundler)

module Xxxx
  class Application < Rails::Application
    config.autoload_paths += [config.root.join('lib')]
    config.encoding = 'utf-8'
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Add additional load paths for your own custom dirs
    # config.load_paths += %W( #{RAILS_ROOT}/extras )

    # Specify gems that this application depends on and have them installed with rake gems:install
    # config.gem "bj"
    # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
    # config.gem "sqlite3-ruby", :lib => "sqlite3"
    # config.gem "aws-s3", :lib => "aws/s3"
    config.gem "rmagick", :version => '1.15.12', :lib => 'RMagick'
    config.gem "rspec-rails", :lib => false

    # Only load the plugins named here, in the order given (default is alphabetical).
    # :all can be used as a placeholder for all plugins not explicitly named
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]

    # Skip frameworks you're not going to use. To use Rails without a database,
    # you must remove the Active Record framework.
    # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]

    # Activate observers that should always be running
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names.
    #config.time_zone = 'Beijing'
    config.active_record.default_timezone = 'Beijing'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
    config.i18n.default_locale = 'zh'

    config.action_controller.session = {
      :session_key => '_xxxx_session',
      :secret      => 'fcfa0df9da9faia9fd9as8fd9as8f98as9fa9idffifa9unjvrqryq87d787b8v78xm8qfu7e8357q46q57x78erz2le89rub7q8758q7ecbr8cwe7rq8ear8ebr7x87',
      :secure      => true
    }

    config.action_controller.session_store = :active_record_store
  end
end
/rake rails:upgrade:configuration結果結束/




# rake rails:upgrade:gems
/rake rails:upgrade:gems結果開始/
# Edit this Gemfile to bundle your application's dependencies.
# This preamble is the current preamble for Rails 3 apps; edit as needed.
source 'http://rubygems.org'

gem 'rails', '3.0.6'

gem 'rmagick', '1.15.12', :require => 'RMagick'
gem 'rspec-rails'
/rake rails:upgrade:gems結果結束/
           

②確定rails2中使用的plugin、在rails3中有替代方案.常用的Plugin在這裡都能找到對應的更新版本。(http://rubygems.org、http://railsplugins.org)

例:rails2

/vendor/plugins/will_paginate

rails3

http://rubygems.org/gems/will_paginate

Gemfile 

 gem "will_paginate", "~> 3.0.4"

3.運作rails3工程,查找文法問題

■Ruby 1.8.7 -> Ruby 1.9.3帶來的修改點

1)所有含有英文以外字元的.rb檔案,第一行追加

# -*- encoding : utf-8 -*-
           

例:

Ruby 1.8

class Site < ActiveRecord::Base
  #ruby1.8不需要加magic comment
end
           

Ruby 1.9

# -*- encoding : utf-8 -*-
class Site < ActiveRecord::Base
  #ruby1.9需要加magic comment
end
           

2)NKF被廢棄例:

Ruby 1.8

NKF.nkf("-s", string)
           

Ruby 1.9

string.to_s.encode("sjis", "utf-8")
           

3)ruby1.9中,使用toutf8等字元轉換的方法需要require 'kconv'

例:

Ruby 1.8

site_id = "string".toutf8
           

Ruby 1.9

require 'kconv'
site_id = "string".toutf8
           

詳細:https://github.com/johnnyhalife/waz-storage/issues/8

4)prec_f被廢棄

例:

Ruby 1.8

1.prec_f
           

Ruby 1.9

1.to_f
           

5)Struct.members.include?方法變更

例:

Ruby 1.8

struct = Struct.new(:id,:name)
struct.members.include?("id")
           

Ruby 1.9

struct = Struct.new(:id,:name)
struct.members.include?(:id)
           

6)Object#tap方法變更

class Campaign < ActiveRecord::Base
  has_many: ads
  
  attr_accessor :tap #屬性恰巧叫tap
end


class Ad < ActiveRecord::Base
  belongs_to: campaign
end
           

Ruby 1.8、rails2

ad = Ad.first
ad.campaign可以正常傳回campaign對象
           

Ruby 1.9、rails3

ad = Ad.first
ad.campaign傳回nil,無法正常傳回campaign對象
           

修改方法:attr_accessor :tap 改變量名

7)String#to_a方法被廢棄

例:

Ruby 1.8

"string".to_a
           

Ruby 1.9

"string".split
           

8)字元串和數組相加結果變更

ids = [1]
str = ""
str += "id = '#{ids}'"
           

例:

Ruby 1.8

結果id = '1'

Ruby 1.9

結果id = '[1]'

■Rails 2.3.16 -> Rails 3.2.13帶來的修改點

▼config、railties相關

9)RAILS_ENV -> Rails.env RAILS_ROOT -> Rails.root 

10)filter_parameter_logging方法廢棄

rails2

filter_parameter_logging :password
           

rails3

config/application.rb中加入

config.filter_parameters += [:password]
           

11)rails3中time_zone_aware_attributes預設開啟

rails2

time_zone_aware_attributes預設關閉

解決方法:

config/application.rb中加入

config.active_record.time_zone_aware_attributes = false
           

如果updated_at、created_at以外的datetime類型字段向插入本地時間,請按解決方法修改。

12)uninitialized constant ActiveRecord::RecordNotFound (NameError) (可能非共通)

rails s啟動時,如果出現該錯誤,在environment.rb添加類定義

require File.expand_path('../application', __FILE__)

module ActiveRecord
  class RecordNotFound < ActiveRecordError
  end
end
           

▼controller相關

13)verify方法廢棄,作為gem使用

解決方法:

①Gemfile中添加gem "verification", "~> 1.0.1"

②我的項目不适用方法①,從gem verification的github取得verification.rb,作為共通方法放到lib/action_controller/verification.rb下

14)error處理

①rails3中clean_backtrace方法廢棄

②rails3中rescue_action_locally方法廢棄

③rails3中rescue_action不會被自動調用問題

①②③的解決方法在下邊例子中給出了。

例:rails2

rescue_from ActionController::RoutingError,
                ActionController::UnknownAction,
                ActiveRecord::RecordNotFound do
      render :partial => '/default/notfound', :layout => true, :status => 404
    end

    def rescue_action(exception)
      if RAILS_ENV == "development"
        logger.error(clean_backtrace(exception))
        rescue_action_locally(exception) 
        return 
      end
      case exception
      when ActionController::RoutingError, ActionController::UnknownAction, ActiveRecord::RecordNotFound
        render :partial => '/default/notfound', :layout => false, :status => 404
      else
        begin
            UserMailer.deliver_email_xxx(
              exception,
              clean_backtrace(exception),
              session.instance_variable_get("@data"),
              params,
            request.env)
          logger.error(exception.message)
          logger.error(clean_backtrace(exception))
        rescue => e
          logger.error(e)
        end
        render :partial => 'error'
      end
    end
           

rails3

rescue_from Exception do |exception|
      rescue_action(exception)
    end

    def rescue_action(exception)
      new_wapper = ActionDispatch::ExceptionWrapper.new(Rails.env, exception)
      if Rails.env == "development"
        logger.error(new_wapper.full_trace)
        raise new_wapper
      end
      case exception
      when ActiveRecord::RecordNotFound
        render :partial => '/default/notfound', :layout => false, :status => 404
      else
        begin
            UserMailer.email_xxx(
              exception,
              new_wapper.full_trace,
              session.instance_variable_get("@data"),
              params,
            request.env).deliver
          logger.error(exception.message)
          logger.error(new_wapper.full_trace)
        rescue => e
          logger.error(e)
        end
          render :partial => 'error'
      end
    end
           

④rescue_from處理方式修改後,發生ActionController::RoutingError、ActionController::UnknownAction異常時,無法遷移到/default/notfound頁面

原因:

rails2: RoutingError、ActionNotFound(UnknownAction)錯誤發生時,被作為異常抛出

rails3: 由于全面導入Rack的關系,現在的Route其實也是一個Rack middleware。是以上邊2個錯誤不再被當作異常抛出(控制台中可以看到錯誤資訊)

解決方法:

config/application.rb

  config.exceptions_app = self.routes

config/routes.rb

  match "/404", :to => "application#not_found"

application_controller.rb 

def not_found 

   render :partial => '/default/notfound', :layout => false, :status => 404 

end

參考資料:http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/

▼model相關

15)find -> where

例:

rails2

self.find(:first, :conditions => ["site_id = ? ", site_id])
self.all(:conditions => ["site_id =? ", site_id], :joins => [:ad], :group => :ad_id)
           

rails3

self.where(["campaign_id = ? ", campaign_id]).first
self.joins( [:ad]).wherel(["site_id =? ", site_id]).group =>(:ad_id)
           

16)named_scope -> scope 

例:

rails2

named_scope :not_delete, :conditions => ["status <> 'delete'"]
           

rails3

scope :not_delete, :conditions => ["status <> 'delete'"]
           

17)validate寫法變更

例:

rails2

validates_presence_of :name
validates_presence_of :succeed_allow_site_id, :if => Proc.new{|site| site.is_succeed_allow_site == '1' }, :message => "必須輸入"

def validate 
  errors.add(:base, "message")
end

def validate_on_create 
  errors.add(:base, "message")
end

def before_save
  self.begin_date = nil if self.check_date_set = "0"
end
           

rails3

validates :name presence=true
validates :succeed_allow_site_id,:presence =>{ :if => Proc.new{|site| site.is_succeed_allow_site == '1' }, :message => "必須輸入"}

validate do
  errors.add(:base, "message")
end

validate(:on => :create) do
  errors.add(:base, "message")
end

before_save do |site|
  self.begin_date = nil if self.check_date_set = "0"
end
           

18)errors#on方法變更

errors#on方法在rails3中仍然存在,但意義不同了

rails2

errors.on(:height)
           

rails3

errors[:height].first
           

19)errors#invalid?方法廢棄

rails2

errors.invalid?(:height)
           

rails3

errors.added?(:height)
           

20)save_without_validation!寫法變更

例:

rails2

site.name = "name"
site.save(false)


site.name = "name"
site.save_without_validation!
           

rails3

site.name = "name"
site.save(:validate => false)


site.name = "name"
site.save!(:validate => false)
           

21)set_table_name -> table_name

例:

rails2

class BigSite < ActiveRecord::Base
  self.set_table_name = sites
end
           

rails3

class BigSite < ActiveRecord::Base
  self.table_name = sites
end
           

22)通過select選項起别名後,rails2和rails3結果不同

背景:sites表中id字段為int型

rails2

record_id = Site.first(:select => "id as record_id").record_id 
           

rails3

record_id = Site.select("id as record_id").first.record_id
           

rails2中record_id為字元串類型,rails3中record_id為int型

23)has_many :through 删除機制改變

背景:

creative.rb	
	has_many :creative_elements, :through => :creative_element_relations
creative_element.rb	
	has_one :creative_element_relation, :dependent => :delete
           

在執行 creative.creative_elements.destroy_all 的時候 

rails2行為

Ⅰ.删除creative_elements資料

Ⅱ.creative_element.rb中dependent語句删除creative_element_relation

rails3行為

Ⅰ.删除creative_element_relations資料

解決方法:

creative_element_relation.rb	
+		belongs_to :creative_element, :dependent => :delete
	creative_element.rb	
-		has_one :creative_element_relation, :dependent => :delete
           

▼views相關

24)<% form_for %> -> <%= form_for %>

Rails2

<% form_for :site, :url=>{:action => 'site_create'} do |f| %>
           

Rails3

<%= form_for :site, :url=>{:action => 'site_create'} do |f| %>
           

25)rails3預設加h

rails2中用h過濾的,rails3中去掉h

Rails2

<%=h site.name %>
           

Rails3

<%= site.name %>
           

rails2中想輸出html代碼的,rails3中加rawRails2

<%= "" if true %>
           

Rails3

<%=raw "" if true %>
           

26)disable_with行為變更

<%= submit_tag '追加', :name => 'add' , :disable_with => "追加"%>
           

解析後代碼

Rails2

if (window.hiddenCommit) { 
  window.hiddenCommit.setAttribute('value', this.value); 
}else { 
  hiddenCommit = document.createElement('input');
  hiddenCommit.type = 'hidden';
  hiddenCommit.value = this.value;
  hiddenCommit.name = this.name;
  this.form.appendChild(hiddenCommit); 
}
this.setAttribute('originalValue', this.value);
this.disabled = true;
this.value='追加';
result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());
if (result == false) { 
  this.value = this.getAttribute('originalValue');this.disabled = false; 
}
return result;
           

Rails3

function disableFormElements(form) {
  form.select('input[type=submit][data-disable-with]').each(function(input) {
    input.store('rails:original-value', input.getValue());
    input.setValue(input.readAttribute('data-disable-with')).disable();
  });
}
           

說明:

rails2會建立隐藏域,controller中params[:add]可以取到值

rails3是将disable_with的submit按鈕全變為不可用

解決方法:

将rails2解析後代碼放到:onclick中。

<%= submit_tag '追加', :name => 'back' , :onclick => "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='追加';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" %>
           

27)link_to的remote,confirm方法失效(非共通)

背景:

rails2時,使用內建在rails架構中的prototype完成link_to的remote,confirm功能。

rails3時,推薦使用jquery gem(也能完成link_to的remote,confirm功能), prototype從rails架構中移出,做成了prototype gem。

問題出現在我對上述背景不了解的時候,沒有在Gemfile中引入prototype。

解決方法:

①rails2時,我的項目既使用了prototype(Hash、escapeHtml等)又使用了jquery(畫面項目控制), 如果你的項目和我一樣,對prototype依賴比較大,可以在Gemfile中引入prototype。

gem "prototype-rails", "3.2.1" 

解決confirm框點OK按鈕後,删除動作token驗證問題在頁面中添加代碼 <%= csrf_meta_tags %>

例:

<%= javascript_include_tag 'xxx' %>
  <%= csrf_meta_tags %>
           

如果你的項目不想使用assets功能,請将gem "prototype-rails", "3.2.1" 指令生成的

C:\Ruby193\lib\ruby\gems\1.9.1\gems\prototype-rails-3.2.1\vendor\assets\javascripts\controls.js、dragdrop.js、effects.js、prototype_ujs.js、prototype.js

放到public/javascript下

并在頁面中引入prototype、prototype_ujs

<%= javascript_include_tag 'prototype' %>
<%= javascript_include_tag 'prototype_ujs' %>
           

②如果你的項目對prototype沒有依賴,推薦使用jquery-railsgem "jquery-rails", "x.x.x" (請參照rails new demo 指令生成的Gemfile)

28)IE8 jquery 日期控件顯示位置不正(非共通)

popup彈出位置通過jquery的width()、height()來計算。

popup彈出位置不正是由prototype更新帶來的。

rails2内嵌的prototype版本為1.6.0.3、gem "prototype-rails", "3.2.1"更新後prototype版本随之更新為1.7

prototype更新對jquery的width()、height()方法産生影響。

解決方法:重寫jquery的_checkOffset方法。

①将下邊代碼放到項目共同js中。

/* == rewrite _checkOffset method ==*/
function calDatePickerOffset(){
$j.extend($j.datepicker,{

	_checkOffset: function(inst, offset, isFixed) {
		var dpWidth = inst.dpDiv.outerWidth();
		var dpHeight = inst.dpDiv.outerHeight();
		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
		if ($j.browser.msie) {
			var viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : ((document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft));
		} else {
			var viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $j(document).scrollLeft());
		}
		if ($j.browser.msie) {
			var viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : ((document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop));
		} else {
			var viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $j(document).scrollTop());
		}

		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $j(document).scrollLeft() : 0;
		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $j(document).scrollTop() : 0;

		// now check if datepicker is showing outside window viewport - move to a better place if so.
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0);
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(dpHeight + inputHeight) : 0);

		return offset;
	}
	});

}

           

②在有日期控件的頁面中調用calDatePickerOffset方法

29)link_to、redirect_to(url_for)方法變更(不清楚是否共通)

現象:當點選有多個參數的link後,沒有參數的link也被添加了不想添加的參數。

例:test.html.erb

link_to 'link_name', :action => 'action_name'
link_to 'link_name_multi_id', :action => 'action_name1', :id => 'first_id', :id2 => 'sec_id'
           

初始化進入該頁面時,産生如下url

/action_name

/action_name1/first_id/sec_id

當點選action_name1連結後,再回到該頁面,産生如下url

/action_name/first_id/sec_id

/action_name1/first_id/sec_id

解決方法:

link_to 'link_name', :action => 'action_name', :id => nil, :id2 => nil
           

PS:

這個問題不清楚是不是共通問題,有可能和我項目的route方式有關,如果你的項目沒有這個問題,請無視。

30)number_to_currency負數輸出格式變更

<%= number_to_currency(-1000000, :precision => 2, :unit => '¥'%>
           

rails2結果

-\ 100,000.00

rails3結果

\- 100,000.00

解決方法:

<%= number_to_currency(-1000000, :precision => 2, :unit => '¥', :negative_format => "%u-%n") %>
           

▼plugin、gems相關

31)mysql -> mysql2

rails3推薦使用mysql2

database.yml

rails2

adapter: mysql

rails3

adapter: mysql2

32)i18n

rails3要求ruby1.9下的i18n,我這裡是i18n(0.6.1)

使用https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale 中相應的xx.yml

替換config/locales/xx.yml

33)will_paginate

①:prev_label -> :previous_label

②array.paginate發生異常

解決方法

environment.rb添加下邊内容

require 'will_paginate/array'

③修改目前頁字型

div.pagination .current{ font-style:normal; } 

34)rmagic取得filesize寫法變更

rails2

require 'RMagick'
   def size(file_path)	
     if !file_path.blank?	
      img_list = Magick::ImageList.new(file_path)	
      img_list = img_list.coalesce	
      return img_list.filesize	
   end
           

rails3

require 'RMagick'
   def size(file_path)	
     if !file_path.blank?	
      img_list = File.open(file_path)	
      return File.size(img_list)
     end
   end	
           

35)不必再使用ez_where(rails3 where可以實作)

rails2

conditions = Caboose::EZ::Condition.new
	conditions << ["status = ?", params[:status]]
	conditions << ["id = ?", params[:id]] unless params[:id].blank?
           

rails3

conditions = model.where("status = ?", params[:status])
	conditions = conditions.where("id = ?", params[:id]) unless params[:id].blank?
           

36)rspec

rspec (1.3.0) -> rspec (2.13.0)

修改過程

Ⅰ.生成新的spec_helper.rb

檔案工程目錄下執行 rails g rspec:install

Ⅱ.删除lib/tasks/rspec.rake檔案

Ⅲ.修改代碼

ⅰ檔案頭添加

# -*- encoding : utf-8 -*-
           

@logger = Logger.new("#{RAILS_ROOT}/log/test.log")
           

@@logger = Logger.new("#{::Rails.root}/log/test.log") 
           

self.fixture_path = RAILS_ROOT + '/spec/fixtures/access_tag/add/' 
           

self.fixture_path = "#{::Rails.root}" + '/spec/fixtures/access_tag/add/'
           

執行單個檔案rspec -cfs spec/models/access_tag/add_spec.rb

執行所有檔案rake spec

執行所有模型rake spec:models

③執行單個測試時沒有問題,整體執行時,部分test_case執行不能通過。

原因:

各個test_case之間沒有清空資料。

修改方法:

spec/spec_helper.rb

config.use_transactional_fixtures = true
           

config.use_transactional_fixtures = false
           

▼其他

37)rails3産品模式log,每次送出中間沒有空行

/usr/local/ruby-1.9.3-p429/lib/ruby/gems/1.9.1/gems/railties-3.2.13/lib/rails/rack/logger.rb

def call_app(request, env)
        # Put some space between requests in development logs.
        if Rails.env.development?
          Rails.logger.info ''
          Rails.logger.info ''
        end
           

解決方法:

将if Rails.env.development?去掉

38)incompatible character encodings: UTF-8 and ASCII-8BIT (非共通)

背景:

sites表的name字段是tinyblob類型

頁面執行到<%=site.name%>時,出錯。

具體原因不明。

解決方法:

<%=site.name.force_encoding("UTF-8")%>
           

歡迎轉載,但請注明出處,并請認真排版。

在ruby-china上也釋出了這片文章,排版好一些(http://ruby-china.org/topics/13446)