0

背景
我们有一个如下的rails迁移脚本:
...
...
0011_update_column1_for_internal_projects.rb
...
...
0022_create_audits.rb

我们为 InternalProject 模型创建了 after_create/update/delete 回调,更新 Audits 表以跟踪模型上发生的事件。

代码片段
DB 迁移脚本 - 0011 - 的self.up方法定义如下:

def self.up  
    InternalProject.all.each do |project|
        project.column1 = project.column2
        project.save!
    end
end  

副作用
使用 0022 脚本时,我们遇到了脚本 0011 无法迁移的情况,因为我们有测试夹具来为内部项目加载一些种子数据。现在这个失败了,因为在保存 InternalProject 时回调被触发,并且在 DB 状态的那一刻,因为 0022 没有运行,审计表不存在,所以我们得到一个 SQL 错误,感叹该表不存在.

我的问题
1. 如何修复 0011 DB 迁移脚本,以防止在保存 InternalProject 时调用回调?我想知道这样做的巧妙方法
2.让我怀疑这样的更新脚本是否会被删除。这是个坏主意吗?我们是否应该在数据库迁移中拥有用于数据操作的脚本?
3. DB迁移脚本应该有数据操作脚本,我们可以做些什么吗?

4

2 回答 2

1

尝试将其放入您的 0011 迁移中

  def self.up  
    InternalProject.all.each do |project|
      project.column1 = project.column2
      project.save(:validate => false) # don't run validations! (notice we're calling `save` and NOT `save!`)
    end
  end
  1. 往上看

  2. 在迁移中操作数据以使其符合模式演变是正常的。但是,在将项目部署到新环境时(例如,第一次部署到生产环境时),您应该运行rake db:create而不是运行迁移。

  3. 不确定我是否理解您的问题,但在迁移中进行数据操作(而不是单独的脚本)是有意义的。把属于一起的东西放在一起。也就是说,没有什么可以阻止您使用单独的迁移文件来迁移数据。

于 2011-01-13T20:02:34.860 回答
0

我最终在代码块中插入了一个 ANSI 兼容的 SQL 脚本,如下所示。想不出任何防故障的方法。

  def self.up
     InternalProject.all.each do |internal_project|
          InternalProject.connection.execute("UPDATE projects SET sales_leader='#{internal_project.owner_name}' where type='InternalProject' and owner_id=#{internal_project.owner_id}")
     end
  end   

如果有人想到/有比这更好的解决方案,请发表您的想法/经验。

于 2011-02-02T17:38:58.557 回答