sql - 如何更新 Rails 中的序列并在我的对象中获取结果值?

标签 sql ruby-on-rails postgresql activerecord sequence

假设我有一个派生自 ActiveRecord 的类。它有几个字段,加上一个“id”字段。创建了“id”,因此它的默认值是序列的“nextval”,因此每次保存新记录时它都会自动递增。它是通过以下方式创建的:

创建序列 id_sequence;

ALTER TABLE my_table ALTER COLUMN id SET DEFAULT nextval('id_sequence');

所以,现在在 Ruby 中,我填充对象中的字段,然后“保存!”它。现在我需要对该对象做更多的工作,但“id”字段仍设置为 nil。 Ruby 中没有“加载”函数可以让我从数据库中重新加载对象。不管你怎么想,“!”在 ActiveRecord 中并不意味着它修改了原始对象(如果 Rails 不遵循它们,Ruby 约定有什么意义)。您似乎无法在原始对象中执行“self.find_by”。我唯一能想到的就是在表的某个定义消息字段上调用“find_by”(这几乎是不可能的,因为那是 id 的用途,但我还没有它!)并创建一个新对象和从中获取 id。

一定有更简单的方法。

最佳答案

Rails ActiveRecord 应该在对象创建时自动用新的 id 更新对象。当同时创建序列和列时,这通常可以正常工作,例如使用串行类型。仅仅将列的默认值设置为 nextval(sequence_name) 不足以将序列“绑定(bind)”到该列。

解决方案似乎是通过设置其所有权将序列与列相关联,如下所示:

ALTER SEQUENCE id_sequence OWNED BY my_table.id;

这应该允许 ActiveRecord 查询 pg 目录并找到要检索的正确序列值。

您可以通过在 alter 语句前后运行 SELECT pg_get_serial_sequence('my_table', 'id') 来检查这一点。之前它可能是空白的,之后它应该显示序列名称(在您的示例中为 id_sequence )。这是 ActiveRecord 为查找适当序列的名称而运行的查询 (line 258 in schema_statements.rb) .

如果这仍然不起作用,我会将序列重命名为约定:tablename_columnname_seq - 因此在您的情况下为 my_table_id_seq

关于sql - 如何更新 Rails 中的序列并在我的对象中获取结果值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30470797/

相关文章:

sql - 如何将这个使用临时表的存储过程的输出转换为物化 View ?

mysql - 如何删除mysql中数字中多余的零?

mysql - 将具有重复值的行转换为列 - MySQL

postgresql - PG 使用 CTE 和 DML 语句的意外行为

mysql - 如果列值不存在,SQL INSERT 新行

ruby-on-rails - 如何让 Brakeman 忽略某些路径

ruby-on-rails - Rails 不生成真实性 token

sql - Rails,迭代组查询的结果

oracle - PostgreSQL 在 Oracle 中是否有类似 "LEVEL"的伪列?

ruby-on-rails-3 - 将列添加到 Rails 3 应用程序中的模型,用于具有从 heroku 转储的模式的数据库