2010-07-17 70 views
2

我發現自己開始利用檢查持久性來讓我的模型「工作」。包含持久性檢查似乎是方便和正確的。另一方面,它感覺有點陰暗,好像我過於謹慎或以小的方式打破ORM抽象。正在檢查DataMapper(或其他ORM)模型是否存在代碼異味?

一個例子可能是:

class Shipment 
    include DataMapper:Resource 

    belongs_to :address, :required => false 

    def shippable? 
    valid? && persisted? && !address.nil? && address.valid? && address.persisted? 
    end 
end 

在這種情況下,我需要告訴我,如果裝運是可交付的方法。這是真實的,當它有效,保存到數據庫,並有地址保存。

另一個例子可能是在回調中使用它來確定某些事情(價格重新計算)是否需要發生。

意見?這是不必要的,偏執的還是安全的,正確的?

回答

2

那麼,如果真的是可能的,你來沒有證實持久性或從數據庫中重新加載執行點貨,檢查持久性似乎絕對必要的我。

但這是真的嗎?你如何得到這個航運行動?我想這裏有兩個工作流程:

  1. 有一個您想要發貨的訂單。你點擊「運送這個狗屎!」並獲得ShipmentsController#new,輸入您的數據。通過按「保存」,您的貨件得到確認並保持有效。持續成功後(我假設shipment.save如果不是,則返回false),您可以直接繼續進行運輸操作(無論需要在那裏完成任何操作)。如果shipment.save告訴你它沒有持續,則#new視圖會被再次渲染,並且尚未執行裝運。所以這就是嚮導的想法-like「gate」的工作流程,只有在持久成功的情況下才允許您執行運輸。

  2. 創建裝運和裝運貨物完全是解耦。可以說一個人計劃發貨,另一個人執行發貨。前者創建一個新的,有效的,持續運輸。後者以易於計劃的貨物清單開始。這ShipmentsController#index使用Shipment.all直接從數據庫加載貨件。不需要檢查persisted?然後在ShipmentsController#perform操作中。

好的。讓我們把它變得更復雜: 現在假設我們處於方案2中,第一個人可以刪除貨物,而第二個人可以刪除貨物,而第二個人執行它。在不考慮這種情況下,天真的應用程序會在#perform完成後再次保存裝運,並設置裝運日期。這將意味着丟失了「刪除」數據庫異常已經發生。但是,不會使用狀態機嗎?因此,我們假設有過渡計劃 - >刪除計劃 - >出貨。如果傢伙#1將狀態設置爲刪除,而傢伙#2正在執行發貨,則狀態機將拋出一個異常:「沒有從刪除轉換到轉移,親愛的!「當試圖更新狀態

所以我不能真正彌補一個情況,明確檢查持久性不是偏執狂,但如果你有一個地方它可能真的發生由於'不安全'的工作流程,你應該檢查持久性。