Ruby on rails 如何访问activerecord初始值设定项中的当前id序列值?

Ruby on rails 如何访问activerecord初始值设定项中的当前id序列值?,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,我正在构建一个activerecord来建模一个对话树,使用数组列类型来表示记录在该树中位置的具体化路径,使用postgres 9.1、rails 4.0和pg gem 我真正想做的是在创建新的对话对象时访问currval('conversations_id_seq'),这样我就可以将[祖父母_id,父母_id…当前_id]作为数组传递给对象初始值设定项。这样,作为数据库约束,我可以指定此列不为null,并且在无父会话的情况下,它仍然默认为[current_id] 我遇到的问题是在第一次保存模型

我正在构建一个activerecord来建模一个对话树,使用数组列类型来表示记录在该树中位置的具体化路径,使用postgres 9.1、rails 4.0和pg gem

我真正想做的是在创建新的对话对象时访问currval('conversations_id_seq'),这样我就可以将[祖父母_id,父母_id…当前_id]作为数组传递给对象初始值设定项。这样,作为数据库约束,我可以指定此列不为null,并且在无父会话的情况下,它仍然默认为[current_id]

我遇到的问题是在第一次保存模型之前访问它的id值。我总是可以放松NOTNULL约束并添加一个after_create钩子,但这感觉很麻烦。我希望有一种方法可以在第一次保存到数据库之前,获取推送到初始化器内@id中的值

alias_attribute :current_id, :id

编辑以澄清赏金:在理想情况下,我可以将一个特殊标记传递给对象的创建方法:Conversation.create(reply_chain:[:lastval]),其中gem将其视为生成的SQL中的lastval()。

如果不需要数据库中的列,可以为该属性设置别名

alias_attribute :current_id, :id
或者,您可以在需要时查询id

def self.last_val
    ActiveRecord::Base.connection.execute("SELECT lastval('conversations_id_seq')")
end

def self.next_val
    ActiveRecord::Base.connection.execute("SELECT nextval('conversations_id_seq')")
end

Conversation.create(reply_chain: Conversation.next_val)

使用after_save也不是最难看的代码。

如果不需要数据库中的列,可以为该属性添加别名

alias_attribute :current_id, :id
或者,您可以在需要时查询id

def self.last_val
    ActiveRecord::Base.connection.execute("SELECT lastval('conversations_id_seq')")
end

def self.next_val
    ActiveRecord::Base.connection.execute("SELECT nextval('conversations_id_seq')")
end

Conversation.create(reply_chain: Conversation.next_val)
保存后使用也不是最难看的代码。

类似于:

def before_create
   self.id=Conversation.connection.execute("SELECT nextval('conversations_id_seq')")
   self.path = [... , self.id];
   true
end
或者使用插入/更新前触发器来维护路径。

类似于:

def before_create
   self.id=Conversation.connection.execute("SELECT nextval('conversations_id_seq')")
   self.path = [... , self.id];
   true
end

或者使用插入/更新前触发器来维护路径。

对于根节点,空路径数组可能比自引用路径数组更有意义,然后路径变成
parent.path+[parent.id]
,序列问题就消失了。对于根节点,空路径数组可能比自引用路径数组更有意义,然后路径变成
parent.path+[parent.id]
,序列问题就消失了。定义last\u val方法与我需要的方法类似,但时间似乎不正确-如果我尝试调用Conversation.create(reply\u chain:[Conversation.last\u val]),例如,最后一个\u val调用将在创建调用之前求值。定义最后一个\u val方法与我需要的方法类似,但时间似乎不合适-如果我尝试调用Conversation.create(reply\u chain:[Conversation.last\u val]),例如,最后一个\u val调用将在创建调用之前求值。啊哈!是的,这显然是我应该做的事情。这或多或少与写的一样(除了connection.execute返回一个PG::Result,您必须从中获取实际的int值)。通过规范,它仍然是并发安全的。通过数据库查询此
SELECT nextval('conversations\u id\u seq')
时,假定现在使用此id,并为实际记录分配递增版本。如果我在一个序列上设置了自动递增并将其分配给一个列,对这个问题有什么建议吗?@M.Habib建议:忽略这个。几乎在所有情况下,您都不关心sequencesAha中的漏洞!是的,这显然是我应该做的事情。这或多或少与写的一样(除了connection.execute返回一个PG::Result,您必须从中获取实际的int值)。通过规范,它仍然是并发安全的。通过数据库查询此
SELECT nextval('conversations\u id\u seq')
时,假定现在使用此id,并为实际记录分配递增版本。如果我在一个序列上设置了自动递增并将其分配给一个列,对这个问题有什么建议吗?@M.Habib建议:忽略这个。几乎在所有情况下,您都不关心序列中的间隙