1

I am trying to do the following:

  validates :price, :presence => true, :if => Proc.new {|p| p.available == true}
  validates :price, :presence => false, :if => Proc.new {|p| p.available == false}

So that if the boolean :available is true, :price must be present, and if it is false, :price must be nil.

But when I test this in the console it doesnt work. Any idea about what am I might be doing wrong?

5
  • See the conditional validation docs; I'm assuming you're trying to enforce not having a price if available is false? Commented Apr 30, 2012 at 18:30
  • That's correct. And I just checked them, but didnt see any clue about what might be wrong... Commented Apr 30, 2012 at 18:31
  • I don't believe validations can be stacked--I was referring you to the "grouping" part. Commented Apr 30, 2012 at 18:36
  • Can you enlighten us, of why would you enforce a price to be nil ? Because as it seems to me, the first validation is just fine... Commented Apr 30, 2012 at 19:38
  • @shuriu I dont necessarily want to force it to be nil, I just want to make sure only one of those two fields is set. If you have a better way to do this, please share it with me and the rest of the internet Commented May 7, 2012 at 11:15

2 Answers 2

2

Yeah, I'm not sure you can stack validations now. However, you may be able to do what you want from a before_validation.

class Foo
  before_validation :price_matches_available

  def price_matches_available
    available ? price.present? : price.nil?
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

EDIT: will that method still work as a validator (marking the object as valid or invalid?). Thanks!
I would say yes, but StackOverflow requires 15 characters for a comments, so yeeeeeeeeeeeees.
2

Based on your comment and from what I can understand you have a Product model, and you want to set the price, only if the products available flag is true.

As per other comments, i don't think you can stack validations... And even if it's possible in some way, I don't think it is good UX to have a validation error like "price must not be set if product is unavailable".

My suggestion is to have only the first validation, and silently reject the price if the flag is set to false. First via javascript for good UX (disable the input when the boolean is checked), and secondly inside a callback to be sure no one tampers with the HTML.

The ruby part can go like this:

class Product < ActiveRecord::Base

  validates   :price, presence: true, if: "available?"

  before_save :reject_price, if: "available? == false"

  private

  def reject_price
    self.price = nil
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.