2014-07-24 46 views
2

所以的情況下想出了在工作中,我想在這裏討論這個問題,因爲我們不能讓我們之間的協議:如何在Rails上正確執行條件只讀記錄?

我們有兩個型號,OrderPassport,它們的方式,訂單HAS_ONE相關護照和護照has_many命令。無論何時訂單完成,其相關護照必須「鎖定」,即變爲只讀(該信息已用於清除海關,因此以後無法更改)。我們要加強在Passport模型規則,我們已經想到了以下選項:

  1. 創建驗證。缺點:當技術上記錄良好時(雖然不能保存),會有記錄產生valid? => false。例如,如果其他記錄上有validates_associated :passport,那可能是一個問題。
  2. 覆蓋readonly?方法。缺點:這會在嘗試更新記錄時引發異常,但您會希望調用save方法不會引發任何記錄。
  3. 創建before_save回調。這有兩種風格:引發異常(非常類似於readonly?選項)或添加@error並返回false停止回調鏈。缺點:在適當的驗證之外添加驗證錯誤可能被認爲是不好的做法。此外,您可能會發現自己撥打valid?並獲得true,然後致電save並獲得false

這種情況讓我們想到了很多關於驗證和Rails之間的關係。這個記錄究竟是什麼意思是valid??這是否意味着save將起作用?

我想傾聽您的意見,以瞭解這種情況。也許最好的方法不是三者之一!謝謝!

回答

0

如何使用readonly!實例方法將此記錄標記爲只讀?見API

你能做到這一點在構造函數中,如:

class Passport < ActiveRecord::Base 
    def initialize(*args) 
    super(*args) 
    readonly! if orders.count>0 # or similar 
    end 
end 
+0

我想,如果護照對象的順序的更新之前初始化將失敗。 – xlembouras

+0

你說得對,這還不夠。 – Grych

+0

與重寫'readonly?'方法不一樣的行爲?我的意思是,當試圖「保存」記錄時會發生什麼?例外? – Ferdy89

0

我覺得這是一個額外的選擇。你所描述的規定Passport模型可以有一些不同的狀態。我會考慮使用狀態機來描述護照的相關訂單狀態。

如:

  • 開放
  • 未決
  • 鎖定
  • other_update_actions ...

考慮到這一點,所有相關的訂單操作將觸發一個事件的護照模型及其狀態。

如果可以將更新操作集成到某些事件中,那麼您可以以更優雅的方式處理readonly部分(不兼容的狀態轉換)。

作爲一個額外的檢查,你總是可以保留一個醜陋的驗證器作爲最後的手段,以防止在沒有狀態機的情況下更新模型。

您可以檢查the aasm gem