2009-06-08 59 views
4

第一項
我希望它保存到數據庫之前驗證字段,以確保它是唯一的(在過去的6個月) 。在Rails中,我如何validates_uniqueness_of:字段的最後6個月,範圍

我想我應該用validates_uniqueness_of:場,CASE_SENSITIVE =>假,範圍=> ...

對於我的應用程序,它只有是如果唯一的,它是< 7個月前使用。

想要將它與created_at進行比較,但並不真正知道如何去做。

第二個項目
我想我應該以某種方式使用.strip之前或文本,使用可能會不小心把在後刪除任何空格(我知道,這些多餘的空格在導軌和如果使用默認他們在那裏可以提出一個獨特的。)

如果任何人有任何提示,應如何做到這一點,我真的很感激它。

回答

3

你也許可以做這樣的事情:

def validate 
    errors.add(:field, 'blah blah') if is_used_recently && !has_unique_field? 
end 

def has_unique_field? 
    Model.exists?(['field = ? and created_at > ?', self.field, 6.months.ago]) 
end 

def is_used_recently 
    self.created_at < 6.months.ago || self.new? # i don't know if created_at would be set by this point 
end 

另外,你可能希望創建一個新的驗證處理程序,或者擴展現有的經過:選項中,如果這就是你要的東西經常做。

要擺脫前導空白和尾隨空白,您需要的方法是「strip」。你可以做這樣的事情運行這個在所有的領域:

before_validation :clean_up_whitespace 

def clean_up_whitespace 
    self.some_field.strip! # this does the strip in place 
end 

我希望這可以幫助,讓我知道,如果我犯任何錯誤!

+0

我不完全認爲你的is_used_recently會爲給定的字段工作,因爲當創建一個新記錄時,self.created_at <6.months.ago == true,但你可以創建超過6個月的第二條記錄以前用相同的值爲:字段 – 2009-06-08 20:12:41

+0

啊我明白了。我讀錯了問題...我會更新我的答案。 – jonnii 2009-06-08 20:21:18

10

validates_uniqueness_of通過檢查給定範圍內給定字段的相同值是否已存在記錄來工作。 :scope可讓您定義唯一性的範圍(顯然);例如,如果我正在創建博客軟件,並且希望每個博客只允許使用一次帖子標題,那麼我可以說validates_uniqueness_of :title, :scope => :blog_id--如果沒有範圍,我只允許在整個系統中使用一次標題。 :scope不會讓你做一個複雜的檢查,就像你想要的那樣。

你可能有什麼需要做的是建立自己的驗證函數來檢查該字段的唯一性問題,給定的時間內(代碼放在模型內):

validate :field_must_be_unique_within_six_months 

def field_must_be_unique_within_six_months 
    return if field.blank? 
    num_duplicates = self.class.count(:conditions => ["field = ? AND created_at < ?", self.field, 6.months.ago]) 
    if num_duplicates > 0 
    errors.add(:field, :taken) 
    end 
end 

field_must_be_unique_within_six_months方法與validates_uniqueness_of的工作方式類似,因爲如果已經有一個具有相同給定字段的記錄,但會添加一個條件以確認日期,它將添加一條錯誤消息。 validate :field_must_be_unique_within_six_months將在保存記錄時將該方法添加到驗證過程中。

爲了驗證在同一時間多個字段不違反乾的,你可以使用validates_each做類似如下:

validates_each :field1, :field2 do |record, attr, value| 
    if record.class.exists?(["#{attr.to_s} = ? AND created_at < ?", value, 6.months.ago]) 
    errors.add(attr, :taken) 
    end 
end 

在上面塊,record是記錄被驗證,attr是屬性(所以field1,field2等)和value是該屬性的值。

相關問題