繁体   English   中英

Rails迁移:可以使用动态代码进行update_all吗?

[英]Rails migration: update_all with dynamic code is possible?

我想在表格中添加一个新字段。

我的用户模型中新的“ secret_code”字段应等于Digest :: SHA1.hexdigest([Time.now,rand] .join)[1..12]。

我想做的是生成一个迁移,该迁移会将字段添加到表中,并用(某种)唯一的“ secret_code”填充我的现有用户。

class AddSecretCodeToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :secret_code, :string
    User.update_all ["secret_code =?", Digest::SHA1.hexdigest([Time.now, rand].join)[1..12]]
  end

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

问题在于此迁移将使用相同的密码填充所有现有用户!

一种解决方案是不使用update_all并运行循环以获取每个用户并向每个用户发送更新,但是在这种情况下,我的迁移将非常缓慢。

有没有一种方法可以将“唯一”随机值发送到update_all方法?

谢谢,奥古斯托

尝试将其更改为Digest::SHA1.hexdigest([Time.now, rand].to_s)但就我个人而言,我将在上面创建一个rake任务,因为它实际上不是迁移。

你的耙子任务会做

User.all.each do |u|
  u.update_attribute(:secret_code, Digest::SHA1.hexdigest([Time.now, rand].to_s))
end

但是,对于您的迁移,我还要将t.string :secret_code, :default => Digest::SHA1.hexdigest([Time.now, rand].to_s)到属性,以便将其添加到新创建的记录中。

对于MySQL,您可以在self.up此权限:

connection.execute(%Q{
    update users
    set secret_code = substring(sha1(rand()) from 1 for 12)
})

PostgreSQL默认不支持SHA1,但是它确实具有MD5,这可能已经足够了:

connection.execute(%Q{
    update users
    set secret_code = substring(md5(random()::varchar) from 1 for 12)
})

如果您安装了pgcrypto软件包,则可以同时使用SHA1。

两者都将使数据库完成所有工作,并避免了往返整个表的所有开销。 如果您想将时间混合在以下内容中,也可以使用一些哈希值:

md5(random()::varchar || now()::varchar) -- PostgreSQL
sha(rand()            || now()         ) -- MySQL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM