ActiveRecord验证url是否存在

cra*_*aig 4 ruby-on-rails ruby-on-rails-4 rails-activerecord

我想确保我的类的url属性有值,如果有,它是有效的:

class Entity < ActiveRecord::Base

  validates :name, presence: true
  validates :url, presence: true, :format => {:with => URI.regexp}

end
Run Code Online (Sandbox Code Playgroud)

在rails控制台中:

> e = Entity.new(name: 'foo')
=> #<Entity id: nil, name: "foo", url: nil, created_at: nil, updated_at: nil> 
Run Code Online (Sandbox Code Playgroud)

这导致url属性出现两个错误:

> 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"]}> 
Run Code Online (Sandbox Code Playgroud)

理想情况下,a nil url会产生单个错误(即can't be blank).

因此,我改变了validates规则:

validates :url, presence: true, :with => Proc.new { URI.regexp if :url? }
Run Code Online (Sandbox Code Playgroud)

但是,我无法使语法工作.我错过了什么?

Yan*_*lly 18

分开两个验证器.

validates :url, presence: true
validates :url, format: { with: URI.regexp }, if: Proc.new { |a| a.url.present? }
Run Code Online (Sandbox Code Playgroud)

(差不多)2周年纪念日编辑

正如vrybas和Barry所说,Proc是不必要的.您可以像这样编写验证器:

validates :url, presence: true
validates :url, format: { with: URI.regexp }, if: 'url.present?'
Run Code Online (Sandbox Code Playgroud)


Bar*_*rry 5

按照Yanis的答案分开验证器,但是你不需要Proc.

如果值是通过设置参数,则可以使用公共验证选项绕过format验证.nilallow_nil

或者,allow_blank如果值为空字符串'',则设置参数也会起作用,如果您url从表单输入进行设置,这可能更有用.

完整的验证器可能如下所示:

validates :url, presence: true
validates :url, format: { with: URI.regexp }, allow_blank: true
Run Code Online (Sandbox Code Playgroud)