zoukankan      html  css  js  c++  java
  • [置顶] 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:Ruby193lib ubygems1.9.1gemsprototype-rails-3.2.1vendorassetsjavascriptscontrols.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)

  • 相关阅读:
    数据预处理
    机器学习--有监督学习和无监督学习
    weka简介
    第10章 接口、继承与多态----类的继承3
    html5 canvas实现梦幻的3D刺猬球
    html5 canvas实现图片玻璃碎片特效
    css3实现的鼠标经过按钮特效
    CSS3 Transitions属性打造动画的下载按钮特效
    纯css3实现的幽灵按钮导航
    几行css3代码实现超炫加载动画
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3278442.html
Copyright © 2011-2022 走看看