2013-08-30 24 views
1

我有一個Rails應用程序,它有這樣的路線:保持ID的無間隙 - Rails的

objects/id 

但每個對象可以被刪除。

因此,如果第一個對象(id = 1)被刪除,對象/ 1將是404 - 找不到。

我想保持這種方式,即如果id = 1的對象被刪除,id = 2的對象變爲id = 1,對象3 id 2等等。

可能嗎?我怎樣才能做到這一點?

+6

這是一個非常非常糟糕的想法,與Rails的工作原理是相反的。具有ID 3的對象應該*總是*具有ID 3,這是REST的要點。每次記錄被刪除時,您都會使系統中的每個網址無效。人們可能會鏈接或書籤到那些突然鏈接到隨機*不同*頁面的頁面。如果您刪除給定URL處的資源,則該URL **應爲** 404,而不會成爲一些隨機的不同資源。這沒有什麼好處,還有許多退步。你絕對應該*不*這樣做。 – meagar

+1

你不應該這樣做!這沒有任何好處。相反,您將無法理解您的歷史日誌或URL。關於activerecord中ID的整個想法是,它們永遠不會改變! – Tilo

+0

謝謝......這使得sence。 –

回答

0

完全不同意這種方法。想想,如果你的模型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,甚至在某些使用情況下你會這樣做,會導致性能大幅降低。

+0

不是級聯外鍵的問題,問題是當ID被保存在某個遠程系統中時,更新無法級聯到每個客戶端的書籤。 – meagar

+0

聽起來不錯,但是如果你的數據被兩個不同的進程修改了,比如兩個不同的web請求,其中一個仍在進行中呢? –

+0

你需要做一些積極的鎖定。我並不是說這不是問題,我只是說*技術上無法克服的問題是,任何給定記錄的刪除都會破壞您網站的所有鏈接。 – meagar

0

它可以在非凡費用完成,並與嚴重的風險徹底搞砸了一切。對事物重新編號也會損壞任何書籤,使其指向錯誤的記錄。簡短的回答:不要做到這一點。

通常情況下:數據庫ID一經分配,不應改變。這有很多好的理由,但最重要的是這個ID將會在很多其他表中被引用,並且所有這些引用也必須被更新。通常沒有簡單的方法來做到這一點。

你應該做的,而是提出一個基於非ID的系統,例如使用slug代替。 Rails的支持路由到這些本身:

def to_param 
    self.slug 
end 

現在你可以某種「彈頭」的分配給將出現在URL,喜歡的東西結束了每一個記錄:在

/users/bob 

暴露的ID這些URL始終不太理想,因爲這些信息可能會泄露未必是公開的信息,並且還會篡改發現可能未被正確保護的其他記錄。