rails migration:缺省字符串为md5的postgresql

问题描述 投票:4回答:2

Rails 3 + postgresql

我想为列的默认值添加一个随机字符串的阴影。

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

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

但是我无法得到它来实际产生任何东西,我使用了反引号,引号等。从我看到的示例中,似乎pg函数仅在SELECT语句中有效。

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

谢谢

ruby-on-rails ruby-on-rails-3 postgresql rails-activerecord rails-migrations
2个回答
5
投票

Rails将尝试解释这一点:

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

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

您的问题是,Rails无法理解诸如使用函数作为列默认值之类的复杂事物,Rails具有一种奇怪而被误导的观念,即您应该在Rails中而不是在数据库中进行所有操作。如果要在默认列中使用函数调用,则可以手动执行alter table

alter table

这将为您提供数据库中所需的默认值,但您可能会注意到connection.execute(%q{ alter table your_table alter column uniqueid set default md5(random()::text) }) 中没有提及新的默认值。如果您想要一个可用的模式,那么您就必须将Rails推开,并使用schema.rb

SQL schema instead by putting this in your application.rb

请注意,SQL模式转储在3.2之前一直被破坏,并且在各种Rails版本中都有模式加载问题(但是您可以始终以application.rb的方式来解决)。然后删除config.active_record.schema_format = :sql ,而改用psql < structure.sql。从好的方面来看,SQL模式转储将跟踪真正的外键,检查约束,触发器等花哨的事物。

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


当然,所有这些都不起作用,因为ActiveRecord太笨了,无法将它无法理解的东西丢掉。 ActiveRecord在解析从数据库获取的表定义时将看到默认值,但是它不理解它,因此它将忽略它。然后,在INSERT期间,ActiveRecord似乎坚持为所有列提供值,即使您没有为其分配值的列也是如此。结果是,即使您已在数据库中附加了明智的默认值,您也将在structure.sql中以NULL结尾。

所以,您如何解决?与ActiveRecord一样,您假装数据库是一个愚蠢的电子表格,并可能使用digest function from pgcrypto钩子在Ruby中进行所有操作。或者,您可以找到比ActiveRecord更少的数据库恶意ORM;我不确定其他ORM能否很好地处理非恒定列默认值。

或者,您可以尝试编写一个BEFORE INSERT触发器,如果​​digest,它将为该列分配默认值。


1
投票

您也可以这样做

© www.soinside.com 2019 - 2024. All rights reserved.