2011-03-23 29 views
1

平臺:鐵3.0 數據庫:MySQL 5.1中導軌」是否有可能知道操作(更新,創建)驗證方法內執行

業務需求:產品的只有一個項目可以在同一時間內發出在發行物品退回後,可以發出同一產品的新物品,可以同時發出不同產品的多個物品

爲了實現上述業務需求,我正在檢查是否已經存在在同一日期範圍內爲同一產品簽發的物品(通過檢查下面我的日期是否有重疊的日期)

 class Item < ActiveRecord::Base 
     validate :validate_one_item_for_product 
     def validate_one_item_for_product 
       items = Item.where("issue_date < ? and return_date > ? and product_id = ?", return_date, issue_date, product_id) 
       errors.add(:base, "item already issued for this product, not returned yet") if items.size > 0 
     end 
    end 

以上定義的驗證對創建工作正常,但在更新的情況下,我需要實現不同的邏輯。我不想爲相同的要求定義兩種方法。所以我想根據是否更新或創建操作來實現與函數的檢查。是否有任何方式可以知道觸發驗證的操作是更新還是刪除?

回答

1

驗證可以在任何時間運行,不只是內createsaveupdate_attributes等等。所以,即使你知道什麼方法觸發了驗證(你可以用caller的輸出進行破解),你不應該使用它,因爲它可能是完全有效的,但完全是意想不到的。

但是,一切都不會丟失。你可以通過調用persisted?來檢查記錄是否已被保存。

class Item < ActiveRecord::Base 
    validate :validate_one_item_for_product, :unless => :persisted? 

private 

    def validate_one_item_for_product 
    items = Item.where(
     "issue_date < ? and return_date > ? and product_id = ?", 
     return_date, issue_date, product_id) 
    if items.size > 0 
     errors.add(:base, 
     "item already issued for this product, not returned yet") 
    end 
    end 
end 
+0

它似乎不贊成使用validate_on_create和validate_on_update,而不是驗證哪些可用於我的情況,而不是:除非=>持續。在這裏,我的擔心是基於更新或基於update或create call定義的方法來創建或添加檢查方法。那麼在這種情況下,您提供的解決方案將無法正常工作,對吧? – 2011-03-23 02:45:59

+0

但在某處,我覺得你告訴我從你的經驗小複雜的事情,因爲我面臨另一個問題也可能與你在這裏建議的相關,請參閱http://stackoverflow.com/questions/5400261/rails-methods-註冊驗證創建上的呼叫更新屬性是 – 2011-03-23 02:46:59

+1

對於一個,做'validate:validate_method_for_create,:除非=>:持久?';對於另一個,'驗證:valiate_method_for_update,:if =>:持久?'。 – yfeldblum 2011-03-23 02:54:50

2

簡單的解決方案是用一個參數定義一個方法來驗證它,然後用不同的:on =>調用進行兩次驗證,然後調用帶有參數的第一個方法。

另外,如果有幫助,您可以使用new_record?它會告訴你,如果正在創建的對象(被保存之前)

+0

謝謝。你可以寫幾行語法:on => call嗎? – 2011-03-23 06:22:13

相關問題