我有一个 Rails 应用程序,它的路线如下:
objects/id
但是每个对象都可以删除。
因此,如果删除了第一个对象(id = 1),则 objects/1 将是 404 - 未找到。
我想以这样的方式保留它,如果 id = 1 的对象被删除,则 id = 2 的对象变为 id = 1,对象 3 变为 id 2 等等。
可能吗?我怎样才能做到这一点?
我有一个 Rails 应用程序,它的路线如下:
objects/id
但是每个对象都可以删除。
因此,如果删除了第一个对象(id = 1),则 objects/1 将是 404 - 未找到。
我想以这样的方式保留它,如果 id = 1 的对象被删除,则 id = 2 的对象变为 id = 1,对象 3 变为 id 2 等等。
可能吗?我怎样才能做到这一点?
它可以以极高的成本完成,并且有完全搞砸一切的严重风险。重新编号也会损坏任何书签,使它们指向错误的记录。简短的回答:不要这样做。
通常:数据库 ID 一旦分配,就不应更改。这有很多很好的理由,但最重要的是,这个 ID 将在许多其他表中被引用,并且所有这些引用也必须更新。通常没有简单的方法可以做到这一点。
相反,您应该做的是提出一个非基于 ID 的系统,例如使用 slug 代替。Rails 原生支持路由到这些:
def to_param
self.slug
end
现在,您可以为将出现在 URL 中的每条记录分配某种“slug”,结果如下:
/users/bob
在 URL 中公开 ID 总是不太理想的情况,因为这些可能会泄露不一定应该公开的信息,并且它们还会导致篡改以发现其他可能未得到适当保护的记录。
完全不同意这种做法。想一想,如果您的模型 A 与其他模型 B 有关系并且模型 A 更改了对象 ID,那么您必须对所有引用对象执行相同的操作。
如果您在某个事务的中间删除某个对象并提交删除并且您的事务直到引用相同的对象ID,该怎么办。那会是个大麻烦。
obj1 = SomeModel.all.first #id = 1
obj2 = SomeModel.all.second #id = 2
现在销毁 obj1
obj1.destroy #now in database obj2 record's id becomes 1
但是 obj2 直到拥有 id 2 (因为没有更新,请记住obj.reload
)。当您尝试保存 obj2 时;这将导致不一致的状态。
所以这在rails中真的不可能修改id,即使在某些用例中你这样做,也会导致性能大幅下降。