如何定义允许名字或姓氏为空但不是两者的自定义验证器
我的个人资料类:
class Profile < ActiveRecord::Base
belongs_to :user
validates :first_name, allow_nil: true
validates :last_name, allow_nil: true
validate :first_xor_last
def first_xor_last
if (first_name.nil? and last_name.nil?)
errors[:base] << ("Specify a first or a last.")
end
end
我尝试通过self first_xor_last函数创建但不起作用。
我接受了这个rspec测试:
context "rq11" do
context "Validators:" do
it "does not allow a User without a username" do
expect(User.new(:username=> "")).to_not be_valid
end
it "does not allow a Profile with a null first and last name" do
profile = Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male")
expect(Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male")).to_not be_valid
end
it "does not allow a Profile with a gender other than male or female " do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"neutral")).to_not be_valid
end
it "does not allow a boy named Sue" do
expect(Profile.new(:first_name=>"Sue", :last_name=>"last", :gender=>"male")).to_not be_valid
end
end
end
我应该通过它。
谢谢,迈克尔。
答案 0 :(得分:1)
首先,allow_nill
不是有效的验证器。您应该使用presence
或absence
。
除非您确实需要同时为这两个字段添加自定义消息,否则无需使用自定义验证程序,只需执行以下操作:
class Profile < ActiveRecord::Base
belongs_to :user
validates :first_name, :last_name, presence: true
end
如果您想允许其中任何一个,可以使用conditional validation:
class Profile < ActiveRecord::Base
belongs_to :user
validates :first_name, presence: true, unless: "last_name.present?"
validates :last_name, presence: true, unless: "first_name.present?"
end
答案 1 :(得分:0)
而不是:
errors[:base] << ("Specify a first or a last.")
DO
errors.add(:base, "Specify a first or a last.")
编辑:
您获得的错误消息不是由您的自定义验证引起的,而是由另外两个似乎不需要的验证引起的,只是摆脱了这两行:
validates :first_name, allow_nil: true
validates :last_name, allow_nil: true
答案 2 :(得分:0)
class Profile < ActiveRecord::Base
belongs_to :user
validate :presence_of_first_or_last_name
def presence_of_first_or_last_name
if (first_name.blank? and last_name.blank?)
errors[:base] << ("Specify a first or a last.")
end
end
end
您可以丢失两个validates :first_name, allow_nil: true
验证,因为它们绝对没有任何效果。
您可能希望使用ActiveSupport方法.nil?
而不是.blank?
,它不仅检查nil,还检查值是空字符串""
还是只包含空格。< / p>
同样正如David Newton所指出的,XOR是eXclusive OR,它是first_name或last_name但不是两者。我尝试根据ActiveModel::Validations
的一般方案命名验证器 - 这是一个描述性名称,用于说明执行何种验证。