validates_uniqueness_of
は、レコードが指定されたスコープ内の指定されたフィールドと同じ値で既に存在するかどうかをチェックすることによって機能します。 :scope
では、一意性の範囲(明らかに)を定義できます。たとえば、ブログソフトウェアを作成していて、ブログごとに投稿タイトルを1回だけ使用したいのであれば、validates_uniqueness_of :title, :scope => :blog_id
と書くことができます。範囲なしでは、システム全体で各タイトルを1回だけ使用できるようにします。 :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
は、レコードの保存時に検証プロセスにメソッドを追加します。
DRYに違反することなく、同時に複数のフィールドを検証するには、次のような何かを行うに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
はその属性の値です。
新しいレコードを作成するときにself.created_at <6.months.ago == trueと表示されるので、is_used_recentlyが指定フィールドで機能するとは思えませんが、6ヶ月以上作成された2番目のレコードを持つことができます前と同じ値で:フィールド –
ああ、私は参照してください。私は間違った質問を読んで...私は私の答えを更新します。 – jonnii
clean_up_whitespaceの情報をありがとう、 私は多くのフィールドでこれを使用していますので、私はsome_fieldをフィールドの配列にして、それらをループするだけで、私はself.variable_name私が自己を削除すると、variable_nameは何ですか。正面からは知っているが、現場には適用されない。私は単純なものを見逃していることを知っている。しかし、それを解決する方法がわからない:( – Datatec