Reputation: 7227
So I was wondering if we can have a conditional allow_nil option for a validation on a rails model.
What I would like to do is to be able to allow_nil depending upon some logic(some other attribute)
So I have a product model which can be saved as draft. and when being saved as draft the price can be nil, but when not a draft save the price should be numerical. how can I achieve this. The following doesn't seem to work. It works for draft case but allows nil even when status isn't draft.
class Product<ActiveRecord::Base
attr_accessible :status, price
validates_numericality_of :price, allow_nil: :draft?
def draft?
self.status == "draft"
end
end
Looking at rails docs I looks like there isn't an option to pass a method to allow_nil?
One possible solution is to do separate validations for both cases
with_options :unless => :draft? do |normal|
normal.validates_numericality_of :price
end
with_options :if => :draft? do |draft|
draft.validates_numericality_of :price, allow_nil: true
end
Any other ways to get this working ?
Thanks
Upvotes: 3
Views: 3624
Reputation: 5332
You don't need allow_nil
then, just use if
:
class Product < ActiveRecord::Base
attr_accessible :status, price
validates_numericality_of :price, if: -> { (draft? && !price.nil?) || !draft? }
def draft?
self.status == "draft"
end
end
Upvotes: 1
Reputation: 11920
You can use if
and unless
to do the following
class Product<ActiveRecord::Base
attr_accessible :status, price
validates_numericality_of :price, allow_nil: true, if: :draft?
validates_numericality_of :price, allow_nil: false, unless: :draft?
def draft?
self.status == "draft"
end
end
With the above, you will have 2 validations set up, one that applies when draft? == true
, which will allow nils, and one where draft? == false
which will not allow nils
Upvotes: 9