Rails 迁移:可以使用动态代码 update_all 吗?
我想在表中添加一个新字段。
我的用户模型中的新“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 方法?
谢谢, 奥古斯托
I'd like to add a new field in a table.
My new "secret_code" field in my User model should be equal to Digest::SHA1.hexdigest([Time.now, rand].join)[1..12].
What I'm trying to do is generate a migration that would add the field to the table and also populate my existing users with a (sort of) unique "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
The problem is that this migration populate all the existing users with the same secret code!
One solution would be NOT to use update_all and run a loop to fetch every user and send an update to each one, but in this case my migration would be extremely slow.
Is there a way to send a "unique" random value to an update_all method?
Thanks,
Augusto
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试将其更改为
Digest::SHA1.hexdigest([Time.now, rand].to_s)
但我个人会为上述内容创建一个 rake 任务,因为它并不是真正的迁移。您的 rake 任务可以
但是,对于您的迁移,我还会添加
t.string :secret_code, :default =>摘要::SHA1.hexdigest([Time.now, rand].to_s)
添加到属性中,以便将其添加到新创建的记录上。Try changing it to
Digest::SHA1.hexdigest([Time.now, rand].to_s)
but personally I'd create a rake task to the above as it's not really a migration.Your rake task would do
However, for your migration I'd also add
t.string :secret_code, :default => Digest::SHA1.hexdigest([Time.now, rand].to_s)
to the attribute so that it is added on newly created records.对于 MySQL,您可以将其直接放入
self.up
中:PostgreSQL 默认情况下不支持 SHA1,但它确实具有 MD5,这可能已经足够了:
如果您有 pgcrypto 软件包后,您就可以对两者使用 SHA1。
这两者都将让数据库完成所有工作,并避免往返整个表的所有开销。如果你想混合时间,你也可以尝试一下你的哈希值:
For MySQL, you could throw this right in your
self.up
:PostgreSQL doesn't have SHA1 support by default but it does have MD5 and that's probably good enough for this:
If you have the pgcrypto package installed then you could use SHA1 for both.
Both of those will let the database do all the work and avoid all the overhead of round-tripping your whole table. You can play around with what you hash a bit as well, if you wanted to mix the time in: