如何重命名列并通过迁移同时更改其类型

Tha*_*anh 21 ruby-on-rails ruby-on-rails-3

在我的general_exams表中,我有一个名为的列semester,类型是string.现在我想将其名称更改为semester_id,type is integer.我已阅读有关迁移的信息,它有可用的转换:

  • rename_column(table_name,column_name,new_column_name):重命名列但保留类型和内容.
  • change_column(table_name,column_name,type,options):使用与add_column相同的参数将列更改为其他类型.

所以,我创建了这样的迁移文件:

class RenameSemesterFromGeneralExams < ActiveRecord::Migration

  def change
    rename_column :general_exams, :semester, :semester_id
    change_column :general_exams, :semester_id, :integer
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,当我跑rake db:migrate,它有错误:

==  RenameSemesterFromGeneralExams: migrating =================================
-- rename_column(:general_exams, :semester, :semester_id)
   -> 0.0572s
-- change_column(:general_exams, :semester_id, :integer)
rake aborted!
An error has occurred, this and all later migrations canceled:

PG::Error: ERROR:  column "semester_id" cannot be cast to type integer
: ALTER TABLE "general_exams" ALTER COLUMN "semester_id" TYPE integer
Run Code Online (Sandbox Code Playgroud)

在我的表GeneralExam中,我销毁了所有数据.所以,任何人都可以告诉我该怎么做?或者我必须创建两个迁移文件?

win*_*ind 17

这适用于Rails 4

def change
  rename_column :general_exams, :semester, :semester_id
  change_column :general_exams, :semester_id, :integer
end
Run Code Online (Sandbox Code Playgroud)


Tig*_*ine 10

您的问题可能是semester包含无法转换的数据integers.这就是你得到施法错误的原因.

我怀疑你需要做更多的工作来完成这项工作,因为唯一想到的就是删除列并创建一个具有正确值的新列.

但是您可以在一次迁移中简单地删除_column然后添加add_column.这应该完美无瑕.

我还建议你先添加add_column,然后执行映射过程,将旧semester值映射到new semester_id,然后删除列.

请记住,您可以在迁移中执行ActiveRecord操作.所以你可以把那些代码放在那里.