Rails迁移:self.up和self.down与change

时间:2012-04-28 15:53:22

标签: ruby-on-rails migration

看起来新的rails版本对self.up和self.down方法有“改变”。

那么当必须回滚迁移时会发生什么,它如何知道要执行的操作。我需要基于在线教程实现以下方法:

class AddImageToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end

  def self.down
    remove_column :users, :image_file_name, :string
    remove_column :users, :image_content_type, :string
    remove_column :users, :image_file_size, :integer
    remove_column :users, :image_updated_at, :datetime
  end    
end

如何使用新的更改方法执行相同的操作?

3 个答案:

答案 0 :(得分:109)

对于许多操作, rails可以猜出反向操作是什么(没有问题)。例如,在您的情况下,回滚时调用的add_column的反向操作是什么?当然是remove_columncreate_table的倒数是多少?它是drop_table。因此,在这些情况下,rails知道如何回滚并定义down方法是多余的(您可以在文档中看到methods currently supported from the change method)。

但请注意,因为对于某种操作,您仍然需要定义down方法,例如,如果更改小数列的精度,如何猜测原始精度回滚?这是不可能的,因此您需要定义down方法。

如上所述,我建议你阅读Rails Migrations Guide

答案 1 :(得分:28)

最好使用Up,Down,Change:

在Rails 3上(可逆):,它应该向上添加新列并仅填充表中的所有记录,并且只删除此列

def up
  add_column :users, :location, :string
  User.update_all(location: 'Minsk')
end

def down
  remove_column :users, :location
end

<强>可是:

您必须避免使用允许节省一些时间的更改方法。例如,如果您在添加后不需要立即更新列值,则会将此代码剪切为如下所示:

def change
  add_column :users, :location, :string
end

在它上面它会向表中添加列并将其删除。更少的代码,这是一个利润。

On Rails 4:在一个地方写下我们需要的更有用的方法:

def change
  add_column :users, :location, :string
  reversible do |direction|
    direction.up { User.update_all(location: 'Minsk') }
  end
end

答案 2 :(得分:1)

class AddImageToUsers < ActiveRecord::Migration
  def change
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end
end