在Rails迁移中从full_name创建first_name和last_name

时间:2016-01-06 05:15:34

标签: sql ruby-on-rails postgresql rails-migrations

我有一个带有全名列的表(人物),但是想要将其拆分为第一个名称(如果存在,则为初始名称)列和姓氏列。

这是一个PostgreSQL数据库FWIW。我正在创建列,所以如果可能的话,它可以在迁移中完成。这些名字都符合旧的标准美国风格,即没有复合名称或连字符。首字母后面没有句点,一些名字只是首字母。这将是一次性更改,然后任何新条目将在其单独的字段中显示名字和姓氏。全名字段将被删除。

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

您可以在单次迁移中执行此操作

创建两个新列

add_column :people, :first_name, :string
add_column :people, :last_name, :string

然后

  full_names = People.all.map(&:full_name)

它返回full_name ['full_name','full_name1',...等新数组]

然后

full_names.each do |n| People.create(first_name:n.split('_')[0],
                                     last_name:n.split('_')[1])
end 

并删除full_name列

remove_column :people, :full_name 

笨拙的解决方案,但应该有效

答案 1 :(得分:0)

确保不要将表架构(数据所在的列)与实际数据(具有这些列的行)混淆。

现在为什么删除last_name 不会删除任何是否有意义。它将保留所有行,但从所有行中删除该列。

所以,正如@xxx所说,添加列(迁移模式),然后填充它们(迁移数据)。

如果要清理从拙劣迁移中创建的所有额外记录,那么请务必备份数据库,然后再运行迁移。 ;)

但也许是一个更有帮助的答案:您可以使用created_at日期查找作为第一次迁移的一部分创建的所有记录,然后删除它们。像

这样的东西
# e.g. if you want to delete all records created since 
# your migration which you ran 2 days ago
People.where("created_at > ?", 2.days.ago).destroy_all

确保在尝试使用数据库之前备份数据库...

然后,回到原始问题,如何将数据从单个名称字段迁移到名/姓。添加新列后,尝试按以下方式迭代每个人:

People.each do |person|
  new_first_name, new_last_name = person.name.split
  person.update_attributes(
    first_name: new_first_name,
    last_name: new_last_name
  ) 
end