克隆的ActiveRecord对象在保存期间向Postgres发送空id

mat*_*don 1 postgresql activerecord ruby-on-rails

我需要保存一个ActiveRecord对象的副本,所以我使用的是:

@original = Model.find(params[:id])
@copy = @original.clone
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将其保存到Postgres时:

PGError:错误:列"id"中的空值违反了非空约束

在控制台中:

@ copy.id
=>无

如何让ActiveRecord不在INSERT语句中发送id列?

更新:

我做了一个小改动后问题就消失了:

@new = Model.new(params[:model])
@original = Model.find(x)
@clone = @original.clone
@new.foreign_key_id = @clone.foreign_key_id
Run Code Online (Sandbox Code Playgroud)

我用最后一行替换了:

@new.foreign_key_id = @original.foreign_key_id
Run Code Online (Sandbox Code Playgroud)

此更改从INSERT语句中删除了"id".在成功完成此更改后,我立即恢复了代码并尝试重现错误.我一直无法重现错误.也许是13日星期五?

EmF*_*mFi 5

你正在调用ActiveRecord :: Base#clone,而不是Object#clone.ActiveRecord :: Base#clone实质上是创建模型的新实例,复制属性hash并删除id键.基本上做的是Luke Franci建议的.

我确定这是一个PostgreSQL问题.因为此代码适用于MySQL.

@clone = @original.clone
@clone.save
Run Code Online (Sandbox Code Playgroud)

您可能遇到的错误与PostgreSQL处理自动增量的方式有关.我无法判断ActiveRecord是否尝试在INSERT语句中传递未定义的id,何时不应该,或者如果定义出现问题.

我不太了解postreges来诊断问题.但我怀疑你的问题的根源可能在定义你的表的迁移中.

出于好奇,结果是Model.new(@original.attributes) == @original.clone什么?