rails迁移:postgresql将随机字符串的md5作为默认值[英] rails migration: postgresql for md5 of random string as default

本文是小编为大家收集整理的关于rails迁移:postgresql将随机字符串的md5作为默认值的处理方法,想解了rails迁移:postgresql将随机字符串的md5作为默认值的问题怎么解决?rails迁移:postgresql将随机字符串的md5作为默认值问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

Rails 3 + postgresql

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

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

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

但是我不能让它实际产生任何东西,我使用了反引号、引号等.从我看到的例子来看,pg 函数似乎只在 SELECT 语句中有效.

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

谢谢

推荐答案

Rails 会尝试解释:

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

作为 Ruby 代码和 :default => md5(...) 在 Ruby 中没有任何意义.如果你引用它,Rails 会认为它是一个字符串,并将 uniqueid 的默认值设置为字符串 'md5(random()::text)',这不会有帮助.

您的问题是 Rails 不理解复杂的事情,例如将函数用作列默认值,Rails 有一个奇怪且错误的观念,即您应该在 Rails 中而不是在数据库中做所有事情.如果你想在默认列中使用函数调用,你可以执行 alter table 手动:

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

这将为您在数据库中获得所需的默认值,但您可能会注意到 schema.rb 中没有提及新的默认值.如果您想要一个可用的架构,那么您当然必须将 Rails 推开,并使用 SQL 架构代替这在你的 application.rb:

config.active_record.schema_format = :sql

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

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

<小时>

当然,这些都行不通,因为 ActiveRecord 太笨了,不能不理会它不理解的东西.ActiveRecord 在解析从数据库中获取的表定义时会看到默认值,但它不会理解它,因此会忽略它.然后,在 INSERT 期间,ActiveRecord 似乎坚持为所有列提供值,甚至是您没有为其分配值的列.结果是,即使您在数据库中附加了一个合理的默认值,您也会在 uniqueid 中得到一个 NULL.

那么,你如何解决这个问题?与 ActiveRecord 一样,您假装数据库是一个愚蠢的电子表格,并在 Ruby 中使用可能的 before_create 钩子来完成所有操作.或者你可以找到一个比 ActiveRecord 更少对数据库不利的 ORM;不过,我不确定其他 ORM 将如何处理非常量列默认值.

或者,您可以尝试编写一个 BEFORE INSERT 触发器,如果​​ NEW.uniqueid IS NULL 将默认值分配给列.

本文地址:https://www.itbaoku.cn/post/1763931.html

相关标签/搜索