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?
You can use the URLConstructor to check if a string is a valid URL. URLConstructor ( new URL(url) ) returns a newly created URL object defined by the URL parameters. A JavaScript TypeError exception is thrown if the given URL is not valid.
Before saving an Active Record object, Rails runs your validations. If these validations produce any errors, Rails does not save the object. After Active Record has performed validations, any errors found can be accessed through the errors instance method, which returns a collection of errors.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With