rails migrate 同名的问题, 当为了图省事的时候,问题就会找上门

users 表结构 ( name, address )

现要让 users 表添加多个地址,于是乎有了下面的 migration

def change
  unless column_exists? :users, :address_id
    add_column :users, :address_id, :string
    User.all.each do |user|
      if user.address.present?
       address =  Address.create( name: user.address, user_id: user.id )
       user.update_column(:address_id, address.id)
      end
    end

    remove_column(:users, address)  end
end

写完 migration , 运行,查看数据库,一切正常。需求继续做下去。由于原本的代码 user 对象有 address 这个属性,并且在许多地方都用到了这个属性,现在这个属性没有了,于是乎,为了方便我便给写了两个同名的方法.

class User < ActiveRecord::Base

  def address
    address = Address.find(address_id) rescue nil
    return address == nil ? "" : address.name
  end

  def address=(addr)
    ...
  end

end

方法写好了,以前的代码调用 address , 功能也正常。省去了很多事情。

git 提交需求,建 merger request . 项目经理看了后,没什么问题,也给合并了。 项目经理运行 migrate 之后,发现该功能上线之后,用户的地址都不见了。而我本地是好的阿,而服务器上,后来创建的数据也存在,而之前用户的地址没有保存下来。项目经理查看数据库,乖乖,之前的用户 address 数据都丢失了。

坏事了, migrate 有问题,看migrate 好像也没有问题阿。仔细想了想,哦,已经来不及半点的后悔。

问题在于 User 类里面的 address 方法, 在本地开发的时候 当运行 migrate 的时候,User 类里面还没有 address 方法, 所以一切正常。当合并之后运行 migrate的时候,是有 address 这个方法的。所以 migrate 里面那个if 都不执行,而在最后又执行了 remove_column , 导致数据丢失。

后来就被项目经理讲了一顿, 也从项目经理那学到了,类似的情况该如何处理。

总结:

1. 数据在进行 migrate 的时候,是很有可能出现问题的。并且有些问题是你很难考虑周全的,人都有疏忽的时候, 犯错误在所难免。

2. 在写 migrate 的时候,特别是删除列、数据 这样的操作,一定要千万小心,不能有半点的自信。

3. 以后写 migrate 的时候,能不用删除数据,就不要删。类似于这样需要删除的情况,可以把当前的列重命名保存起来。等新的表结构确实没有问题的时候(通常是过一段时间的考验)。再删除这些数据不迟。

4. 偷懒须谨慎

时间: 2024-08-10 23:17:33

rails migrate 同名的问题, 当为了图省事的时候,问题就会找上门的相关文章

Ruby on Rails Tutorial 第二章 之 用户资源&amp;MVC&amp;REST

说明:用户资源包括用户数据模型和这个模型相关的Web页面. 1.用户数据模型如下: 2.使用Rails内置的脚手架生成用户资源中,执行如下所示命令: $ rails generate scaffold User name:string email:string    #创建模型 $ rails destroy scaffold User    #销毁模型 $ bundle exec rake db:migrate   #用Rake来迁移数据库,为了使用Gemfile中指定的Rake版本,通过bu

UML - 2 其他类型的图

1. 对象图(Object Diagram) 对象图也叫实例图(instance diagram)是系统运行的某一瞬间的对象的一个快照.对象图用来展示连接的对象. 2.包图(Package Diagram) 包图描述的结构层次在类图之上.便于跟清晰地描述大型系统.包用来把类进行分组.包也是一个划分命名空间的单位,不同的包里可以有同名的类.包图的一个重要作用是展示包之间的依赖关系.在OO原则中有6个原则用来指导包的划分.他们是REP(发布与重用等价原则),CCP(统一封闭原则,类比于类划分的单一职

Windows安装Redmine 2.5.2不完全指南

我决定在项目中引入Redmine来管理开发任务和计划,至于Redmine的好处,请问度娘或者脑补一下. 互联网搜索到的,基本上都是旧版本的, 1.2.1 的最多,我要新的啊,所以只好自己来啦. 本文主体参考 Redmine Wiki 的安装页面:http://www.redmine.org/projects/redmine/wiki/RedmineInstall,遇到的问题自己解决了一下.总之不是翻译,而是实践记录. 环境描述 服务器操作系统为Windows Server 2008 R2 Ent

Windows下安装Redmine 2.5.2不全然指南

我决定在项目中引入Redmine来管理开发任务和计划,至于Redmine的优点,请问度娘或者脑补一下. 互联网搜索到的.基本上都是旧版本号的. 1.2.1 的最多,我要新的啊,所以仅仅好自己来啦. 本文主体參考 Redmine Wiki 的安装页面:http://www.redmine.org/projects/redmine/wiki/RedmineInstall,遇到的问题自己攻克了一下. 总之不是翻译,而是实践记录. 环境描写叙述 服务器操作系统为Windows Server 2008 R

版本控制的简介

CVS采用客户端/服务器架构设计,版本库位于服务器端,实际上就是一个RCS文件容器.每一个RCS文件以“,v”作为文件名后缀,用于保存对应文件的历次更改历史.RCS文件中只保留一个版本的完全拷贝,其他历次更改仅将差异存储其中,使得存储变得更加高效.图1-1展示了CVS版本控制系统的工作原理,可以看到作为RCS文件容器的CVS版本库和工作区目录结构的一一对应关系. CVS成功地为后来的版本控制系统确立了标准,像提交(commit).检入(checkin).检出(checkout).里程碑(tag或

Android实战技巧之二十四:横竖屏切换

这几年一直在做手机上和电视盒的App,几乎没有考虑过横竖屏切换的问题.电视盒好说,横屏不变,你要是给它设计个竖屏人家也没机会使:而手机上的应用就不好说了,有些界面你设计了横竖屏兼容可能是为了表示你的功能强大.但是按照惯例,或许也是设计师图省事,我们只是做一个方案.就像目前主流的App都只有竖屏一个模式,比如微信.京东和招商银行.我截了几张图表示一下. 但是像地图之类的应用,也许横屏会显示的更友好一些.请看腾讯地图的设计如下: 细心的你会发现,地图的横竖屏的样式几乎是一样的布局,调整起来还是比较容

Ubuntu 14.04安装redmine

公司要安装项目管理系统,采用redmine,新来的我就来做这个小小的任务了,中途也出过几次问题,搭建redmine,他的依赖包很多,所以我建议用apt装,下面开始吧. 首先升级一下源 apt-get update apt-get upgrade 更新完成 PS:(如果图省事,可以选择LAMP套件安装,此处指mysql和apache此处不用套件安装了 ) 安装apache2和apache2的一个模块 apt-get install apache2 libapache2-mod-passenger

Java异常处理总结Exception\Error

Java异常处理总结Exception\Error 2012-12-28 08:17:17|  分类: JAVA |  标签:java  |举报|字号 订阅 Java异常处理总结 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出现,那么你每个地方都要做相同处理,感觉相当的麻烦! Java语言在设计的当初就考虑到这些问题,提出异常处理的框架的方案,

java学习之Eclipse开发工具

Eclipse是功能强大Java集成开发工具.它可以极大地提升我们的开发效率.可以自动编译,检查错误.在公司中,使用的就是Eclipse进行开发. 1.1     Eclipse的下载.安装.卸载 l  下载 http://www.eclipse.org l  安装 (只需要解压后就能使用) l  卸载(只需要将文件夹删除就可以了) l  注意: 开发软件的安装目录中,尽量不要出现空格与中文 1.2     Eclipse的使用 在当前阶段,我们只需要完成最基本的Java文件编写,其他功能跟随日