所以我有一个用户模型和一个相应的表(用户),其中包含以下字段:User_id,用户名,密码等。
但后来我将invitation_limit添加到users表中。新创建的用户有invitation_limit,但是在运行invitation_token迁移之前创建的用户没有invitation_limit字段。
如何更新以前创建的用户以包含invitation_token字段?请注意,我不是在谈论将invitation_limit字段添加到用户表(即迁移),而是更新已创建的用户。
谢谢,
答案 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代码,因此您可以访问应用程序可以访问的所有数据。更改数据,添加缺失数据,删除行等
一些快速提示: