为什么不使用我的ActiveRecord :: Migration子类创建上下方法?

时间:2011-11-26 04:31:35

标签: ruby-on-rails

我正在阅读Rails 3 in Action并按顺序执行命令。但是,当我运行命令

rails new things_i_bought
cd things_i_bought
bundle install
rails generate scaffold purchase name:string cost:float

这本书说我应该得到这个代码:

class CreatePurchases < ActiveRecord::Migration
          def self.up #not created in my code
            create_table :purchases do |t|
              t.string :name
              t.float :cost
              t.timestamps
            end
end
          def self.down # not created in my code
            drop_table :purchases
end
 end

我改为使用此代码:

class CreatePurchases < ActiveRecord::Migration
  def change
    create_table :purchases do |t|
      t.string :name
      t.float :cost

      t.timestamps
    end
  end
end

为什么不为我创建上下类方法?我正在使用 rails 3.1.1和ruby 1.9.2。

3 个答案:

答案 0 :(得分:11)

感谢您阅读我的书!

正如JacobM和dbalatero已经解释过的,这是Rails 3.1中的一个新功能。 Aaron Patterson添加了这一特殊功能,作为简化迁移语法的一种方法。在早期版本的Rails中,您必须按照本书所示进行操作:

class CreatePurchases < ActiveRecord::Migration
  def self.up
    create_table :purchases do |t|
      t.string :name
      t.float :cost
      t.timestamps
    end
  end

  def self.down
    drop_table :purchases
  end
end

但这有点重复自己。 Aaron创建了一个看起来很好且更简单的迁移语法,只调用了向前迁移所需的方法,但也允许向后迁移(称为“回滚”)。使用Rails 3.1语法编写的相同迁移是:

class CreatePurchases < ActiveRecord::Migration
  def change
    create_table :purchases do |t|
      t.string :name
      t.float :cost
      t.timestamps
    end
  end
end

因此,当此迁移“向前”运行时,Rails将使用字段创建购买表。当你向后滚动(或者“向后”运行)时,Rails会知道放下桌子。

然而,这种语法并不完全完善,并且您会遇到change_column等方法的问题。当发生这种情况时,最好坚持在迁移中定义def updef down方法:

class CreatePurchases < ActiveRecord::Migration
  def up
    change_column :purchases, :cost, :integer
  end

  def down
    change_column :purchases, :cost, :float 
  end
end

那是因为在这个例子中Rails不知道如何将它切换回以前的类型。我希望这能更好地解释它!

答案 1 :(得分:1)

这是new feature in Rails 3.1。对于Rails可以找出如何反转的更改,例如创建表,您只需创建一个“更改”方法,其中包含可能已经“up”的代码,并且它会找出如何自行执行“down”操作

您也可以自己定义“向上”和“向下”方法 - 对于某些更改(例如删除列),Rails将无法弄清楚 - 但语法有点不同;它不只是def up而不是def self.up(它们现在是实例方法而不是类方法)。

答案 2 :(得分:0)

我相信新的Rails 3.1,数据库迁移方法可以自我意识到如何运行向上/向下迁移。

因此,如果您定义def change方法,它会尝试使用这些自我感知方法:在这种情况下,create_table知道在DROP TABLE中执行down上下文,CREATE TABLE上下文中的up

如果你想要旧样式,你可以继续使用它并定义你自己的self.downself.up方法。

编辑:这是关于此博客文章的链接,名为“可逆迁移”:http://www.edgerails.info/articles/what-s-new-in-edge-rails/2011/05/06/reversible-migrations/index.html