`

Rails migration 和model 的validations检查冲突时

阅读更多
    今天,干活的时候,遇到这样的一个问题,我们的一个系统有很多版本,有些客户由于种种原因始终使用的是比较早期的版本,姑且说2.03版本吧。

有这样一个migration

class AddFreqAnalyzers < ActiveRecord::Migration
#055_add_freq_analyzers.rb
  def self.up
    add_column :analyzers, :start_freq, :int
    add_column :analyzers, :stop_freq, :int
    startFreq=ConfigParam.get_value(ConfigParam::StartFreq);
    stopFreq=ConfigParam.get_value(ConfigParam::StopFreq);
    puts startFreq
    puts stopFreq
    Analyzer.find(:all).each { |a|
      a.start_freq=startFreq;
      a.stop_freq = stopFreq;
      a.save
    }
    1;
  end

  def self.down
    remove_column :analyzers, :start_freq
    remove_column :analyzers, :stop_freq
  end
end

主要的作用是添加了两个字段和给这个字段赋值。

然后,我们2.06版本的时候给一个model加了一个字段,很正常的我们给这个字段加了validation的保存检查。然后,我们测试升级

class AddWebApiUrl < ActiveRecord::Migration
#085_add_web_api_url.rb
  def self.up
    add_column :analyzers, :api_url, :string,  :null => true
  end

  def self.down
    remove_column :analyzers, :api_url
  end
end

并且在model中增加检查如下:
  validates_format_of     :api_url,
                          :with =>/(^(rubyscript:|http:\/\/|https:\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)|^about:blank$|^$/ix  


然后,一直没有什么问题,包括正常的升级。然而,在一个用户那里他们的系统是2.02的那么系统升级的话,就会把migration从040一直运行。结果报了错,如下:

引用
== 55 AddFreqAnalyzers: migrating =============================================
-- add_column(:analyzers, :start_freq, :int)
   -> 0.0136s
-- add_column(:analyzers, :stop_freq, :int)
   -> 0.0033s
2000000.0
52000000.0
rake aborted!
undefined method `api_url' for #<Analyzer:0x2aaaae4533b8>



错误提示是没有定义api_url方法,实际上055版本的migrate根本没有api_url的字段,只有到085才有,可是代码里已经有了validation的检查,所以,升级过程就出错了。这样的错误还真奇怪了一阵子,最后,怎么解决的呢:

  validates_format_of     :api_url,
                          :with =>/(^(rubyscript:|http:\/\/|https:\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)|^about:blank$|^$/ix,
                          :if => Proc.new { |record| record.respond_to? :api_url}	


这就和
  validates_format_of     :email,
                          :with => /(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z|^$)/i,
                          :if => Proc.new { |analyzer|analyzer.email.length >0 }   

一样表示只有特定条件才进行检查。


下面是同样的例子:

class CreateVendors < ActiveRecord::Migration
  def self.up
    create_table :vendors do |t|
      t.string :name
      t.string :email
    end    a = Vendor.new(:name => “Fred Flinstone”, :email => “fred@example.com”)
    a.save!
    b = Vendor.new(:name => “Barney Ruble”, :email => “barney@example.com”)
    b.save
  end
  def self.down
    drop_table :vendors
  end
end


model:

validates_presence_of :rating, :on => :create, :message => "can't be blank"



出错提示:

引用
$ rake db:migrate
(in .... )
== 2 CreateVendors: migrating =======================================
rake aborted!
Validation failed: Rating can't be blank(See full trace by running task with --trace)


解决如下:


  validates_presence_of :rating, :on => :create, :message => "can't be blank",
    :if => Proc.new { |record| record.respond_to? :rating }


原文作者的解释关于respond_to?
引用
responds_to asks the Rails model: “Do you have a method named ‘rating’?”. Because Rails magically creates methods for every column an entity has in the database, Rails will either have that method (because it has been defined in the database), or not (because no such column exists). So we only run the validation if we have the column, avoiding the mess with trying to validate data that doesn’t make sense (yet).

0
0
分享到:
评论

相关推荐

    rails-practice-validations:一个 repo 设置,以便您可以练习验证

    在这个"rails-practice-validations"项目中,你可以尝试创建不同类型的验证,并通过运行测试来检查验证是否生效。这将有助于加深对Rails验证机制的理解,提高开发效率,同时保证应用程序的数据质量。通过不断的练习...

    Ruby+for+Rails

    Ruby on Rails(简称Rails)是基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式,旨在提高开发效率和代码可读性。 1. **Ruby的安装** 在不同的操作系统上,安装Ruby的方式有所不同。在...

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...

    使用Rails上传和转换视频

    在Ruby on Rails(Rails)框架中,上传和转换视频是一个常见的需求,特别是在构建涉及多媒体内容的Web应用时。Rails提供了一系列工具和库,使得开发者能够方便地处理这种任务。本篇文章将详细介绍如何在Rails中实现...

    rails 项目起步示例

    Rails是Ruby语言的一个著名Web开发框架,全称为Ruby on Rails,它遵循MVC(Model-View-Controller)架构模式,旨在提高开发效率和代码可读性。本示例"rails项目起步示例"是一个购物系统,非常适合初学者入门学习。 ...

    Rails项目源代码

    Ruby on Rails,通常简称为Rails,是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式。这个“Rails项目源代码”是一个使用Rails构建的图片分享网站的完整源代码,它揭示了如何...

    railsAPI

    在Rails API中,模型(Model)代表应用程序的数据结构,它与数据库交互,处理数据验证和业务逻辑。视图(View)是用户看到和与之交互的部分,而控制器(Controller)作为模型和视图之间的协调者,处理用户请求并决定...

    Ruby on Rails入门经典代码

    Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...

    Rails3常用命令行命令

    Rails的scaffold命令是一个强大的工具,可以快速生成一套完整的CRUD(Create, Read, Update, Delete)界面,包括Model、View和Controller。例如,创建一个名为Person的资源: ```bash rails g scaffold person name...

    rails指南 中文版

    Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,强调“约定优于配置”(Conventions over Configuration)和“Don't Repeat Yourself”(DRY,不要...

    Ruby on Rails安装指南(Ruby 1.8.6+Rails 2.0.2)

    Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer 版本,并安装 Ruby。然后,下载 Rails 2.0.2 版本,并安装。接下来,需要安装 Mongrel 服务器。...

    Rails入门教程一(翻译).pdf

    Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式,强调“约定优于配置”和“Don't Repeat Yourself”(DRY)原则,从而提高开发效率。 本教程首先会...

    Ruby on Rails中文指南

    Ruby on Rails,简称Rails,是一款基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,旨在提升开发效率和代码的可读性。Rails以其“约定优于配置”的设计理念,以及“DRY(Don't Repeat ...

    rails2-sample

    Ruby on Rails是一种基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)设计模式。它以其优雅的语法、高效的开发速度以及“约定优于配置”的理念而闻名于世,极大地简化了Web应用的开发过程。此外,...

    Ruby on Rails 教程 - 201406

    本教程“Ruby on Rails 教程 - 201406”可能是针对2014年6月时的Rails版本,那时候Rails正处于3.x或4.x系列,虽然现在Rails已经发展到6.x版本,但基础概念和核心原则依然适用。 在Rails中,Model负责处理数据和业务...

    rails2.3.2

    Ruby on Rails(通常简称为 Rails)是一个基于 Ruby 语言的开源 Web 应用程序框架,它遵循 Model-View-Controller (MVC) 设计模式,用于构建数据库驱动的 Web 应用程序。Rails 强调“约定优于配置”(Convention ...

    关于rails 3.1 cucumber-rails 1.2.0

    Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...

    ruby on rails轻松使用

    14. **数据库迁移(Database Migrations)**: 当数据库结构需要变化时,使用`rails generate migration`创建迁移文件,然后通过`rails db:migrate`来执行迁移。 15. **Rails Console**: 交互式的命令行工具,可以...

    中文版rails教程

    Ruby的语法优雅,支持块、闭包和元编程,这使得Ruby在编写Rails应用时能够实现高度的灵活性和可扩展性。 **Rails框架核心组件** 1. **模型(Model)**:模型是应用的核心,负责处理数据和业务逻辑。ActiveRecord是...

Global site tag (gtag.js) - Google Analytics