validates_presence_of

A handy little method to ensure that one field, another or both are present.

  def self.validates_presence_of_either(*attrs)
    options = { :message => "One of #{attrs.to_sentence} must be set", :on => :save,
      :error_key => attrs.collect { |a| a.to_s }.join("_") }
    options.update(attrs.pop) if attrs.last.is_a?(Hash)
        
    send(validation_method(options[:on])) do |record|
      has_error = true
      attrs.each do |attr|
        value = record.send(attr)
        unless value.blank?
          has_error = false
        end
      end
      
      if has_error
        record.errors.add(options[:error_key], options[:message])
      end
    end
  end


Then use as follows:

validates_presence_of_either :foo, :bar, :message => “Please set foo and/or bar!”

Sunday, August 1, 2010