在Rails迁移中向现有表添加列

时间:2011-01-29 02:48:20

标签: ruby-on-rails-3

我有一个需要:email列的用户模型(我忘了在初始脚手架中添加该列)。

我打开了迁移文件并添加了t.string :emailrake 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

11 个答案:

答案 0 :(得分:511)

如果您已经运行了原始迁移(在编辑之前),则需要生成新的迁移(rails generate migration add_email_to_users email:string将执行此操作)。然后执行rake db:migrate,它将运行新的迁移。

如果您尚未运行原始迁移,则只需编辑它,就像您尝试的那样。您的迁移代码几乎完美:您只需要完全删除add_column行(该代码尝试在创建表之前向表中添加列,以及您的表创建代码已经更新,无论如何都包含t.string :email

答案 1 :(得分:100)

在rails console

使用此命令
rails generate migration add_fieldname_to_tablename fieldname:string

rake db:migrate

运行此迁移

答案 2 :(得分:28)

Sometimes rails generate migration add_email_to_users email:string produces a migration like this

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

In that case you have to manually an add_column to change:

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

And then run rake db:migrate

答案 3 :(得分:22)

您也可以

rake db:rollback

如果您尚未向表中添加任何数据。然后通过向其添加电子邮件列来编辑迁移文件,然后调用

rake db:migrate

如果您的系统中安装了rails 3.1,则此功能将起作用。

更简单的方法是更改​​让迁移文件中的更改保持原样。 使用

$rake db:migrate:redo

这将回滚上次迁移并再次迁移。

答案 4 :(得分:18)

要添加列,我只需按照以下步骤操作:

  1. rails generate migration add_fieldname_to_tablename fieldname:string

    <强>替代

    rails generate migration addFieldnameToTablename

    生成迁移后,编辑迁移并定义您希望该列添加的所有属性。

    注意:Rails中的表名总是复数(以匹配数据库约定)。 使用前面提到的其中一个步骤的示例 -

    rails generate migration addEmailToUsers

  2. rake db:migrate

    1. 您可以从db/schema.rb更改架构,在SQL查询中添加所需的列。
    2. 运行此命令:rake db:schema:load

      警告/注意

      请记住,运行rake db:schema:load会自动清除表格中的所有数据。

答案 5 :(得分:4)

您也可以使用列之前或之后将列添加到特定位置,例如:

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

答案 6 :(得分:3)

当我完成此操作时,我创建了一个新的,只使用up部分中的add列和下部的drop列。

如果您在两者之间进行迁移,您可以更改原始文件并重新运行,但在这种情况下,我认为这会导致迁移无法正常运行。

正如目前发布的那样,您正在添加列,然后创建表格。

如果您更改订单可能会有效。或者,在修改现有迁移时,只需将其添加到create table,而不是单独添加列。

答案 7 :(得分:1)

如果您的表已经存在,您还可以使用force: true强制表格中的表格。

示例

ActiveRecord::Schema.define(version: 20080906171750) do
  create_table "authors", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

答案 8 :(得分:1)

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

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

答案 9 :(得分:0)

您可以通过

回滚上次迁移
rake db:rollback STEP=1

或通过

回滚此特定迁移
rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

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

答案 10 :(得分:0)

你也可以这样做..   rails g migration add_column_to_users email:string

然后rake db:migrate   还添加:用户控制器中的电子邮件属性;

了解更多详情,请查看http://guides.rubyonrails.org/active_record_migrations.html