web-dev-qa-db-ja.com

Railsモデルの条件付き検証

モデルに対して条件付き検証を行おうとしているRails 3.2.18アプリがあります。

呼び出しモデルには、:location_id(事前定義された場所のリストへの関連付け)と:location_other(誰かが文字列またはこの場合はアドレスを入力できるテキストフィールド)の2つのフィールドがあります。

私ができるようにしたいのは、:location_idまたは:location_otherのいずれかが存在することが検証されている場所への呼び出しを作成するときに検証を使用することです。

Rails検証ガイドを読みましたが、少し混乱しています。条件付きでこれを簡単に行う方法について誰かが光を当てることができると期待していました。

11
nulltek

私はこれがあなたが探しているものだと信じています:

class Call < ActiveRecord::Base
  validate :location_id_or_other

  def location_id_or_other
    if location_id.blank? && location_other.blank?
      errors.add(:location_other, 'needs to be present if location_id is not present')
    end
  end
end

location_id_or_otherは、location_idlocation_otherが空白かどうかをチェックするカスタム検証メソッドです。両方がそうである場合、検証エラーが追加されます。 location_idlocation_otherの存在が排他的論理和である場合、つまり、2つのうち1つだけが存在でき、どちらも存在できない場合、両方ではなく、メソッドのifブロックに次の変更を加えることができます。

if location_id.blank? == location_other.blank?
  errors.add(:location_other, "must be present if location_id isn't, but can't be present if location_id is")
end

代替ソリューション

class Call < ActiveRecord::Base
  validates :location_id, presence: true, unless: :location_other
  validates :location_other, presence: true, unless: :location_id
end

このソリューション(のみ)は、location_idlocation_otherの存在が排他的論理和である場合に機能します。

詳細については、 Rails検証ガイド を確認してください。

19
Joe Kennedy