我想做一个简单的基于正则表达式的电子邮件验证:
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value =~ /\A([\S]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
record.errors[attribute] << (options[:message] || 'is not an email')
end
end
end
Rails 文档中提到了这一点。我已经用 rubular 进行了检查,一切正常,但是在 rails 中,本地地址中带有点的电子邮件由于某种原因无法通过验证(john.doe@example.com)。奇怪的是它接受任何其他非空白字符(例如 &^%#!*() 当然不包括@)。
class User < ApplicationRecord
validates :email, presence: true, length: { maximum: 64 },
uniqueness: { case_sensitive: false }, email: true
validates :password, presence: true, length: { in: 8..64 }
validates :first_name, length: { in: 2..16 }, allow_blank: true
validates :last_name, length: { in: 2..32 }, allow_blank: true
validates :student_id, length: { in: 5..6 }, allow_blank: true,
numericality: true
end
和失败的测试:
test 'should validate email with special characters in local address' do
@user.email = 'john.doe@domain.com'
assert @user.valid?
end
整个 user_test.rb
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(email: 'johndoe@domain.com', password: 'password12',
first_name: 'John', last_name: 'Doe',
student_id: '112233')
end
# Presence validation
test 'user validate user' do
assert @user.valid?
end
test 'should not validate empty email' do
@user.email = ''
assert_not @user.valid?
end
test 'should not validate blank password' do
@user.password = ' '
assert_not @user.valid?
end
test 'should validate blank first name' do
@user.first_name = ''
assert @user.valid?
end
test 'should validate blank last name' do
@user.last_name = ''
assert @user.valid?
end
test 'should validate blank student id' do
@user.student_id = ''
assert @user.valid?
end
# Length validation
test 'should not validate too long email' do
@user.password = 'a' * 65
assert_not @user.valid?
end
test 'should not validate too long password' do
@user.password = 'a' * 65
assert_not @user.valid?
end
test 'should not validate too short password' do
@user.password = 'a' * 7
assert_not @user.valid?
end
test 'should not validate too long first name' do
@user.first_name = 'a' * 17
assert_not @user.valid?
end
test 'should not validate too short first name' do
@user.first_name = 'a'
assert_not @user.valid?
end
test 'should not validate too long last name' do
@user.last_name = 'a' * 33
assert_not @user.valid?
end
test 'should not validate too short last name' do
@user.last_name = 'a'
assert_not @user.valid?
end
test 'should not validate too long student id' do
@user.student_id = '1234567'
assert_not @user.valid?
end
test 'should not validate too short student id' do
@user.student_id = '1234'
assert_not @user.valid?
end
# Email format validation
test 'should not validate email with wrong format' do
@user.email = 'john.doe@domain'
assert_not @user.valid?
end
test 'should validate email with special characters in local address' do
@user.email = 'john.doe@domain.com'
assert @user.valid?
end
test 'should not validate email with special characters in domain' do
@user.email = 'john.doe@dom_ain.com'
assert_not @user.valid?
end
# Numeric-only validation
test 'should not validate student id with non-numeric characters' do
@user.student_id = 'ab123c'
assert_not @user.valid?
end
# Uniqueness validation
test 'should not validate duplicated email' do
@copycat_user = @user.dup
@user.save
assert_not @copycat_user.valid?
end
end
知道这种奇怪行为的原因是什么吗?