我想在表格中添加一个新字段。
我的用户模型中的新“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方法发送“唯一”随机值?
谢谢, 奥古斯托
答案 0 :(得分:4)
尝试将其更改为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)
添加到该属性中,以便将其添加到新创建的记录中。
答案 1 :(得分:3)
对于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