如何使用Rails 3样式迁移(def更改)识别迁移方向(向上或向下)?

时间:2011-10-06 18:34:02

标签: ruby-on-rails ruby-on-rails-3 migration rails-migrations

我非常喜欢Rails 3样式的迁移,即一个change方法足够聪明,可以识别是否正在安装或回滚迁移,因此我不必编写up和{ {1}}方法相互镜像。但我有一种情况,我需要在回滚迁移时跳过一些代码(更新我正在添加的down列)。

我看了http://guides.rubyonrails.org/migrations.html,但第5节末尾的例子也遇到了同样的问题:

counter_cache

回滚此迁移时,不需要更新class AddFuzzToProduct < ActiveRecord::Migration class Product < ActiveRecord::Base end def change add_column :products, :fuzz, :string Product.reset_column_information Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' } end end 字段。有没有办法防止它?

我尝试查看fuzz但由于Rails足够聪明以反向执行迁移,因此在删除列之前执行更新。此外,在定义Product.column_names方法时,似乎忽略了任何changeup方法。还有其他想法吗?

4 个答案:

答案 0 :(得分:61)

仅供将来参考,对于Rails 4,最好的方法是使用可逆:

def change
  # ...change code...

  reversible do |dir|
    dir.up do
      # ...up-only code...
    end
  end
end

请参阅http://guides.rubyonrails.org/migrations.html#using-reversible

答案 1 :(得分:20)

在这种情况下,我认为您必须像往常一样使用updown方法。不要担心,尽管在Rails 3中添加了change,但据我所知,这些方法并不适用于斩波块。必要时继续使用它们。

修改:这是一个选项:覆盖migrate

class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end

  def change
    add_column :products, :fuzz, :string
  end

  def migrate(direction)
    super # Let Rails do its thing as usual...

    if direction == :up # ...but then do something extra if we're going 'up.'
      Product.reset_column_information
      Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
  end
end

思想?

答案 2 :(得分:19)

在rails 3.x中你也可以这样做

class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end
  def change
    add_column :products, :fuzz, :string
    unless reverting?
      # Do this only when direction is up
      Product.reset_column_information
      Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
  end
end

答案 3 :(得分:0)

这是一个令人讨厌的想法:@connection是CommandRecorder,当它失败时。

def change
    add_column :products, :fuzz, :string
    unless @connection.kind_of?(ActiveRecord::Migration::CommandRecorder)
        Product.reset_column_information
        Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
end

没试过。显然你不在Rails API之外,所以它可能随时都会中断。

如果只有改变方法有合法的方法来确定迁移方向......