Katie M
Katie M

Reputation: 1131

Rails 3 Validation with Scope Conditions

I have an invoice model with approver_note, po_number and state_id.

I need validations to check:

validates :approver_note, :presence => true, {:scope => state_id == 3}
validates :po_number, :presence => true, {:scope => state_id ==2}

So, if the user selects state_id = 3, he must enter a note. If he selects state_id = 2, he must enter a po_number.

Any assistance would be great... thanks!

Upvotes: 5

Views: 5275

Answers (1)

Rob Davis
Rob Davis

Reputation: 15772

You're looking for the :if option instead of :scope.

validates :approver_note, :presence => true,
  :if => lambda { |invoice| invoice.state_id == 3 }

But since a lambda is a little ugly, I'd probably add a method to encapsulate what you're doing a bit better:

validates :approver_note, :presence => true, :if => :requires_note?
validates :po_number, :presence => true, :if => requires_po_number?

def requires_note?
  state_id == 3
end

def requires_po_number?
  state_id == 2
end

If you actually have a bunch of different attributes that are required when state_id is 3, not just a note, then you may want something like this:

validates :approver_note, :presence => true, :if => :green_state?
validates :po_number, :presence => true, :if => orange_state?

def green_state?
  state_id == 3
end

def orange_state?
  state_id == 2
end

(Replace "green" with -- I dunno -- "high_documentation" or whatever makes sense in your world.)

Or maybe you want to let the state decide what it is:

def green_state?
  state.green?
end

It really does help to make the terminology in your code adhere more closely to your real-world language, as opposed to "3" and "2".

Upvotes: 7

Related Questions