5

Rails 3 + postgresql

我想要一个随机字符串的 sha 作为列的默认值。

所以,在我的迁移中,我有:

t.string :uniqueid, default: md5(random()::text)

但是我不能让它真正产生任何东西,我使用了反引号、引号等。从我看到的示例中,似乎 pg 函数仅在SELECT语句中有效。

那准确吗?关于如何实现这一目标的任何想法?

谢谢

4

2 回答 2

6

注意:如果您使用的是更新版本的 Rails,您可能想查看brcebn 的答案。


Rails 将尝试解释这一点:

t.string :uniqueid, default: md5(random()::text)

作为 Ruby 代码,:default => md5(...)在 Ruby 中没有任何意义。uniqueid如果你引用它,那么 Rails 会认为它是一个字符串并为该字符串设置默认值,'md5(random()::text)'这将无济于事。

如果要在默认列中使用函数调用,可以alter table手动执行:

connection.execute(%q{
    alter table your_table alter column uniqueid set default md5(random()::text)
})

这将使您在数据库中获得所需的默认值,但您可能会注意到在您的schema.rb. 如果你想要一个可用的模式,那么你必须使用SQL 模式,而不是将它放在你的application.rb

config.active_record.schema_format = :sql

然后删除你的schema.rbstructure.sql改用。请注意,SQL 模式转储在 3.2 之前被破坏,并且在各种 Rails 版本中存在模式加载问题(但您总是psql < structure.sql可以解决这个问题)。从好的方面来说,SQL 模式转储将跟踪花哨的东西真正的外键、检查约束、触发器......

顺便说一句,如果您真的想要 SHA ,那么您需要查看digest.pgcrypto

于 2013-03-01T15:24:54.847 回答
5

你也可以做

t.string :token, default: -> { "md5((random())::text)" }, null: false

编辑:即使这会生成一个 32 位的随机字符串,也并不意味着它是唯一的。我是这么认为的,但我只是遇到了唯一索引错误。

于 2020-03-17T14:35:16.840 回答