我有一个用户模型,它需要一个:email列(我忘记在初始脚手架期间添加该列)。

我打开迁移文件并添加t.string:email,执行rake db:migrate,并得到一个NoMethodError。然后我加了一行

add_column :users, :email, :string

再次rake db:migrate,再次NoMethodError。我是不是漏了一步?

编辑:这是迁移文件。

class CreateUsers < ActiveRecord::Migration  
  def self.up  
    add_column :users, :email, :string  
    create_table :users do |t|  
      t.string :username  
      t.string :email  
      t.string :crypted_password  
      t.string :password_salt  
      t.string :persistence_token  

      t.timestamps  
    end  
  end  

  def self.down  
    drop_table :users  
  end  
end

当前回答

有时,rails生成add_email_to_users email:string生成这样的迁移

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
  end
end

在这种情况下,你必须手动修改一个add_column:

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :email, :string
  end
end

然后运行rake db:migrate

其他回答

有时,rails生成add_email_to_users email:string生成这样的迁移

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
  end
end

在这种情况下,你必须手动修改一个add_column:

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :email, :string
  end
end

然后运行rake db:migrate

你也可以在迁移中使用特殊的change_table方法来添加新列:

change_table(:users) do |t|
  t.column :email, :string
end

你也可以使用before column或after column将列添加到特定位置,如下所示:

rails generate migration add_dob_to_customer dob:date

迁移文件将生成除::email之外的以下代码。需要在“::email”后或“::email”前添加

class AddDobToCustomer < ActiveRecord::Migration[5.2]
  def change
    add_column :customers, :dob, :date, after: :email
  end
end

您可以通过回滚上一次迁移

rake db:rollback STEP=1

或回滚此特定的迁移

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

编辑文件,然后再次运行rake db:mirgate。

如果您已经运行了最初的迁移(在编辑它之前),那么您需要生成一个新的迁移(rails生成迁移add_email_to_users email:string就可以了)。 它将创建一个包含以下内容的迁移文件: Add_column:用户,电子邮件,字符串 然后执行rake db:migrate,它将运行新的迁移,创建新列。

如果您还没有运行最初的迁移,您可以编辑它,就像您正在尝试做的那样。您的迁移代码几乎是完美的:您只需要完全删除add_column行(该代码试图在创建表之前向表添加列,并且您的表创建代码已经更新为包含t.string:email)。