Rails conditional validation in model

activerecord, rails-activerecord, ruby-on-rails, ruby-on-rails-3, validation

Solution

I believe this is what you're looking for:

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` is a custom validation method that checks if `location_id` and `location_other` are blank. If they both are, then it adds a validation error. If the presence of `location_id` and `location_other` is an exclusive or, i.e. only one of the two can be present, not either, and not both, then you can make the following change to the `if` block in the method.

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

Alternate Solution

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

This solution (only) works if the presence of `location_id` and `location_other` is an exclusive or.

Check out the Rails Validation Guide for more information.

Problem

I have a Rails 3.2.18 app where I'm trying to do some conditional validation on a model. In the call model there are two fields :location_id (which is an association to a list of pre-defined locations) and :location_other (which is a text field where someone could type in a string or in this case an address). What I want to be able to do is use validations when creating a call to where either the :location_id or :location_other is validated to be present. I've read through the Rails validations guide and am a little confused. Was hoping someone could shed some light on how to do this easily with a conditional.

Original source