Rails迁移在另一个表中创建条目时更新现有记录

时间:2011-07-12 17:38:16

标签: sql ruby-on-rails migration sql-update insert-update

我正在尝试为我的Rails应用程序设置Beta Invites。我有一个邀请模型和一个用户模型。

用户有一个invitation_id。我正在验证用户必须有一个invitation_id,它应该是唯一的。我想编写一个迁移,以便我可以更新现有用户以获得invitation_id。

这是我的邀请函:

# Table name: invitations
#
#  id              :integer         not null, primary key
#  sender_id       :integer
#  recipient_email :string(255)
#  token           :string(255)
#  sent_at         :datetime
#  created_at      :datetime
#  updated_at      :datetime

为了保证唯一性,我必须在邀请表中创建记录,并将相应的ID分配给用户记录。

有人可以建议迁移吗?

提前致谢!

1 个答案:

答案 0 :(得分:7)

如果您已经为邀请和用户进行了迁移,那么您应该将邀请填充到自定义rake任务中。始终是一种很好的做法,可以严格控制表格操作。

/lib/tasks/distribute_invitations.rake

namespace :db do
  desc "Run all custom tasks"
  task :import_all => [:distribute_invitations, :some_other_data_import]

  desc: "Some other data import"
  task :some_other_data_import => :environment do
    puts "insert task code here"
  end

  desc: "Give existing user's invitations"
  task :distribute_invitations => :environment do
    for user in User.all
      if user.invitation_id.nil?
        invite = Invitation.create(:sender_id => <some id>, :recipient_email => <some email>, :token => <some token>, :sent_at => Time.now)
        user.update_attribute(:invitation_id, invite.id)
        puts "Updated user #{user.id} with invitation_id #{invite.id}"
      else
        puts "User already has an invitation_id"
      end
    end
  end
end

执行迁移后,为users表提供了invitation_id,您可以运行:

rake db:distribute_invitations

您的现有用户将通过invitation_id创建邀请并与之关联。

或者运行您可以执行的所有任务:

rake db:import_all

在这种情况下,您可以通过“用户迁移”将其粘贴到迁移中:

class AddInvitationID < ActiveRecord::Migration
  def self.up
    add_column :users, :invitation_id, :integer
    for user in User.all
      if user.invitation_id.nil?
        invite = Invitation.create(:sender_id => <some id>, :recipient_email => <some email>, :token => <some token>, :sent_at => Time.now)
        user.update_attribute(:invitation_id, invite.id)
        puts "Updated user #{user.id} with invitation_id #{invite.id}"
      else
        puts "User already has an invitation_id"
      end
    end
  end

  def self.down
    remove_colum :users, :invitation_id
  end
end