LoginSignup
7
6

More than 3 years have passed since last update.

Rails vaildates uniquness

Last updated at Posted at 2019-05-19

以下のようなモデルがあるとする。

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
7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6