如何在Rails中更改记录的主ID?

 rails console
 u = User.find(9)
 u.id = 7#没有其他id为7的记录
 u.save
 =>是的
 User.all

id没有改变。

如何更改主ID? 为什么会阻止此操作?

在Rails 3.0.7和PostgreSQL中工作。

编辑:由于有充分的理由不这样做,我会解释原因,希望这是一个很好的理由。

我们正在对暂存进行可用性测试,因此我希望它看起来像生产,以便让每个人都轻松。 我不希望在可用性测试过程中产生混淆或错误,方法是在Staging上按一个顺序排序,在Production上按不同的顺序排列。 我只在Staging DB上更改了一个PK id。

不要在生产数据库上执行此操作!

我不确定为什么它会阻止这种行为,但它肯定会阻止它。

您可以使用update_all方法为用户绕过此操作。

User.where(id: 7).update_all(id: 9) 

虽然如果可能的话,你真的应该避免这样做。

对我来说工作:

 User.find(9).update_column(:id, 7) 

@Jason指出了一个非常有效的观点。 我完全同意他的观点。 但是,你可能有自己的理由,我建议你重新考虑一下你要做的事情。

回答你的问题:

默认情况下,ID列受质量分配保护,无法手动设置。 但是,您可以通过定义方法来覆盖此行为:

 def self.attributes_protected_by_default [] # ["id", ..other] end 

这将允许您手动分配ID。

你能详细说明你的用例是什么吗? 为什么要更改ID? 你真的想用它做什么?

通常这样做是个坏主意,Rails不会让你轻易做到这一点,因为它会破坏你的数据完整性!

这就是为什么:当您在下面使用关系数据库(如PostgreSQL)时,您将在模型之间建立关系,这意味着您将使用模型的ID作为其他相关模型中的参考…这意味着如果您更改一个条目的ID,对该条目的所有引用都将过时并破坏您的数据库。

我强烈建议再次分析您的要求,并尝试找到另一种方法来完成您需要做的事情(不更改ID)

另一种方法(虽然它不是纯Rails)是创建一个新列,并用新ID填充它。

然后,使用数据库管理软件(不是Rails),从id列中删除主键属性,删除它,将最近添加的列重命名为“id”,并为其指定主键属性。 (如果您不能直接在数据库软件中执行此操作,请设置属性Unique,Auto-Increment等)

您也可以将列移到前面(MySQL语法):

 ALTER TABLE table_name MODIFY COLUMN id int(11) FIRST; 

但还有另一件事我真的想说。 它在这个问题上并没有像我在其他地方看到的那么糟糕,但人们:告诉人们它通常不是一个好主意,这一切都很好,但这不是问题的答案。 除非你已经知道这个人的用例,否则请不要说“不要这样做”。

在其他论坛上,人们对“为什么要这样做?”感到非常沮丧。 或“不要那样做”,然后不回答这个问题。 他们已经知道这不是标准做法,他们没有给我信任,他们认为我并不知道这不是一个普通的用例。

这个页面上的人并没有那么糟糕,我不是想挑选他们。 我只是在告诫:请在假设讲课之前检查一下自己的行为。 有人问了一个问题,虽然警告可能是一个好主意,但假设他们有一个想要答案的原因可能是安全的。

咆哮结束。

ID通常由数据库生成为自动递增PK。 你不能(实际上不应该)修改它。