2012-04-19 181 views
1

如何驗證具有自定義或虛擬作用域的屬性的唯一性?我想過使用虛擬屬性,但它一直試圖在數據庫中查詢audit_year。我寧願不爲此唯一性約束創建另一個數據庫列。如何驗證虛擬屬性範圍上的Rails模型屬性唯一性

每個位置每年只能安排一次審計,所以我需要從計劃屬性中提取年份並驗證該範圍內的唯一性。

class Audit 
    attr_accessible :location_name, :scheduled_date, :completion_date ... 

    validates :location_name, :presence => true, :uniqueness => { :scope => :audit_year } 

    ... 

    def audit_year 
     scheduled_date.year 
    end 

end 

我甚至可能沒有在我的虛擬屬性嘗試正確的路徑。什麼是在軌道上做到這一點的「正確」方式?

回答

0

我知道這有點晚了,但我想我會介入。我從記憶中這樣做,所以你可能需要擰這一點。

我的第一個想法是在你的audit_year方法中,你可以查詢數據庫的所有年份。就像:

def audit_year 
    !self.class.select('selected_date').map{ |a| a.selected_date.year }.include?(selected_date.year) 
    # or using Rails 3.2 and Ruby 1.9.3: 
    # !self.class.pluck('created_at').map(&:year).include?(selected_date.year) 
end 

我假設的唯一方法是,如果它返回false,它將無法驗證。這段代碼只從你的類中選擇一列(我使用self.class而不是審計,因此它更可重用),然後將年份映射到數組。如果包含(true),則返回相反的(!)。您可能可以使用uniq優化查詢,但這取決於表格的大小,無論是否有必要。

另一個選擇是爲屬性推出自己的驗證器,這真的不會那麼困難。唯一的區別是除了上述之外,您還需要添加一條有條件地檢查selected_date.present?的行。一個很好的資源是Rails的回調和錯誤指南,如果你不知道如何:http://guides.rubyonrails.org/active_record_validations_callbacks.html

希望有所幫助。