ActiveRecordであるカラムとあるカラムが同じ値になるのを防ぐようなValidationを定義する

例えば、GitHubの通知やTwitterの通知、あるいはQiitaの通知のような機能を実現するためにActiveRecordを利用する例を考えます。このとき「通知元のユーザと通知先のユーザは被ってほしくないなあ」という制約を実現するめに、ExclusionValidator が利用できます。exclusion: { in: :xxx } のように :in オプションにSymbolを与えると、その名前のインスタンスメソッドの実行結果に対して重複していないかどうか検査してくれるので、これを利用します。下の例では #invalid_receivers というインスタンスメソッドを定義しています。

class Notification < Activerecord::Base
  belongs_to :receiver # 通知先のユーザ
  belongs_to :sender   # 通知元のユーザ

  validates :receiver, exclusion: { in: :invalid_receivers }

  private

  # @return [Array<User>]
  def invalid_receivers
    [sender]
  end
end

以上です。