以下のようなモデルがあるとする。
create_access_permission.rb
class CreateAccessPermission < ActiveRecord::Migration
def change
create_table :project_expirations do |t|
t.reference :user
t.datetime :expired_at
t.timestamps
end
end
end
このモデルは、あるユーザに対してアクセスパーミッションを発行する時に使われる。
このパーミッション自体は expired_at
に値が入っていない場合に有効。
レコードが作成された段階では expired_at
に値はない。
validation
ユーザに、有効なアクセス権を重複して付与しないようにしたい。
そこで、以下のような validationを書いていた。
class AccessPermission
validate :not_duplicate_permission
def not_duplicate_permission
self.where(user_id: user_id).where.not(expired_at: nil).exist?
end
end
けど、以下のようにかけることを知った。
(なぜか nil
との掛け合わせで uniqueness
を検証することは出来ないと思いこんでいた。)
class AccessPermission
validates :uniqueness, :user_id, { scope::expired_at }
end
より簡潔に
さらにこんなふうなメソッドがあることを知った
class AccessPermission
validates_uniqueness_of :user_id, scope: expired_at
end
さらにさらにより多くのカラムとの組み合わせも実現できる。
(今回のモデルの場合は必要ないけど、)
class SampleModel
validates_uniqueness_of :user_id, scope: [:expired_at, :email]
end
さらに組み合わせ時の条件も指定できる
class SampleModel
validates_uniqueness_of :email, conditions: -> { where.not(deleted_at: nil) }
end