zoukankan      html  css  js  c++  java
  • 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. 偷懒须谨慎

  • 相关阅读:
    linux服务篇
    降智比赛题解
    CF 1437 题解
    ZR 2020普转提七连测day5
    20联赛集训day11 题解
    contest5 题解
    20联赛集训day9 题解
    20联赛集训day8 题解
    contest4 题解
    20联赛集训day7 题解
  • 原文地址:https://www.cnblogs.com/laoquans/p/3982834.html
Copyright © 2011-2022 走看看