rrauenza
rrauenza

Reputation: 6993

Enforce mutually exclusive fields' presence in rails

This code isn't working for me, but the debugger does trigger, and the values are what I expect for my test case:

validates :a, :presence => false, :if => Proc.new { |f| debugger; f.b.present? }
validates :b, :presence => false, :if => Proc.new { |f| debugger; f.a.present? }

Goal: a and b should never be defined at the same time.

If I understand the syntax, a's presence should be false if b is present. And similar for b.

Am I misunderstanding this? I do believe the data is recorded via save! .. but then I've already confirmed the validations are being called. I looked at the object immediately after obj.save! and the obj.errors has an empty messages hash.

Upvotes: 1

Views: 1020

Answers (2)

oneWorkingHeadphone
oneWorkingHeadphone

Reputation: 899

Something that might make this simpler would be to call a custom validation that just checks if either is present using self without calling length or creating a proc.

validate :are_mutually_exclusive

private

def are_mutually_exclusive
  if self.a.present? && self.b.present?
    errors.add(:your_error_key, 'Values for A and B are mutually exclusive')
  end
end

These are also easier to manage if you have grouped values. E.g. A & B are allowed together, but neither A or B is allowed with C

if (self.a.present? || self.b.present?) && self.c.present?

Upvotes: 2

rrauenza
rrauenza

Reputation: 6993

The problem is not with the 'if' logic -- presence: false is NOT the opposite of presence: true

Reference: Rails 3 Validation :presence => false

I ended up using:

validates :a, length: {is: 0}, if: Proc.new { |f| f.b.present? }
validates :b, length: {is: 0}, if: Proc.new { |f| f.a.present? }

Upvotes: 0

Related Questions