ActiveRecord validate url if it is present
I would like to ensure that my class's url
property has a value and if it does, it is valid:
class Entity < ActiveRecord::Base
validates :name, presence: true
validates :url, presence: true, :format => {:with => URI.regexp}
end
In the rails console:
> e = Entity.new(name: 'foo')
=> #<Entity id: nil, name: "foo", url: nil, created_at: nil, updated_at: nil>
Which results in two errors for the url
attribute:
> e.valid?
=> false
> e.errors
=> #<ActiveModel::Errors:0x007fed9e324e28 @base=#<Entity id: nil, name: "foo", url: nil, created_at: nil, updated_at: nil>, @messages={:url=>["can't be blank", "is invalid"]}>
Ideally, a nil
url
would produce a single error (i.e. can't be blank
).
As such, I've change the validates
rule:
validates :url, presence: true, :with => Proc.new { URI.regexp if :url? }
I can't get the syntax to work, however. What am I missing?
Separate your two validators.
validates :url, presence: true
validates :url, format: { with: URI.regexp }, if: Proc.new { |a| a.url.present? }
(almost) 2 year anniversary edit
As vrybas and Barry state, the Proc is unnecessary. You can write your validators like this:
validates :url, presence: true
validates :url, format: { with: URI.regexp }, if: 'url.present?'
Separate the validators as in Yanis's answer, but you don't need a Proc for this.
You can use the common validation options to bypass the format
validation if the value is nil
by setting the allow_nil
parameter.
Alternatively, setting the allow_blank
parameter would also work if the value is the empty string ''
, which may be more useful if you're setting url
from an form input.
The complete validator could look like this:
validates :url, presence: true
validates :url, format: { with: URI.regexp }, allow_blank: true