将新字段添加到预先存在的表并在Rails中修改以前创建的数据

时间:2010-01-25 06:54:11

标签: mysql ruby-on-rails sqlite migration

所以我有一个用户模型和一个相应的表(用户),其中包含以下字段:User_id,用户名,密码等。

但后来我将invitation_limit添加到users表中。新创建的用户有invitation_limit,但是在运行invitation_token迁移之前创建的用户没有invitation_limit字段。

如何更新以前创建的用户以包含invitation_token字段?请注意,我不是在谈论将invitation_limit字段添加到用户表(即迁移),而是更新已创建的用户。

谢谢,

4 个答案:

答案 0 :(得分:4)

不应将种子数据放入迁移中。迁移用于创建结构,而不是添加数据,如果您移动数据库,则会遇到问题。

你可以写一个rake任务。如果您创建一个名为“generate_invitation_token”的实例方法,则可以编写这样的rake任务:

# lib/tasks/invitation_tokens.rake
namespace :seed do
  desc "generate invitation tokens for users that don't have one already"
  task :user_tokens => :environment do
    User.all(:conditions => {:invitation_token => nil}).each do |user|
      user.generate_invitation_token
    end
  end
end

然后您可以从命令行调用rake任务,如下所示:

rake seed:user_tokens

这是一种更干净的方法。

<强>更新

我在一篇名为“Adding Columns and Default Data To Existing Models”的博文中扩展了这个答案。

答案 1 :(得分:1)

不幸的是,普遍接受的策略是添加另一个填充这些字段的迁移。当然,您不能使用活动记录(或者您的迁移可能会中断),因此最佳做法是在pure SQL中执行此操作。

答案 2 :(得分:1)

我的理解是你要更新用户记录,而不是创建种子(种子向数据库添加数据,例如Roles ans等,这对你的应用程序很重要)。来自documentaion

class AddReceiveNewsletterToUsers < ActiveRecord::Migration
  def self.up
    change_table :users do |t|
      t.boolean :receive_newsletter, :default => false
    end
    User.update_all ["receive_newsletter = ?", true]
  end

  def self.down
    remove_column :users, :receive_newsletter
  end
end

您也可以在迁移中使用模型:

User.all(:conditions => {}).each do |user|
  user.do_sth
  user.save
end

依此类推,请阅读about caveats

编辑:
在你的评论之后,我认为你应该在迁移中这样做;

class AddInvitationLimitToUser < ActiveRecord::Migration
  def selt.up
    change_table :users do |t|
      t.integer :invitation_limit # and add validation to model `validates_presence_of` and so on
    end
    # now update all records already in database, which didn't had value in invitation_limit column
    User.update_all ["invitation_limit = ?", 5]
  end

  def self.down
    remove_column, :users, :invitation_limit
  end
end

答案 3 :(得分:0)

您希望为此使用迁移。迁移只是ruby代码,因此您可以访问应用程序可以访问的所有数据。更改数据,添加缺失数据,删除行等

一些快速提示: