def validate_uuid_format(uuid)
uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
return true if uuid_regex.match?(uuid.to_s.downcase)
log_and_raise_error("Given argument is not a valid UUID: '#{format_argument_output(uuid)}'")
end
因此,将属性验证为UUID的关键是生成一个UuidValidator类,并确保Rails的内部能够自然地找到并使用它。 受www.example.com的Doug Puchalski提供的coderwall.comsuggested解决方案的启发,结合Rails API docs,我提出了以下解决方案:
# lib/uuid_validator.rb
class UuidValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value =~ /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
msg = options[:message] || "is not a valid UUID"
record.errors.add(attribute, msg)
end
end
end
现在,假设您示例化了一个新的Lot示例,并错误地将一个整数作为外键分配给material_id:
lot = Lot.new({material_id: 1})
lot.material_id
=> "1" # note the auto type cast based on schema definition
lot.valid?
=> false
lot.errors.messages
=> {:material_id=>["is not a valid UUID"]}
# now, assign a valid uuid to material_id
lot.material_id = SecureRandom.uuid
=> "8c0f2f01-8f8e-4e83-a2a0-f5dd2e63fc33"
lot.valid?
=> true
重要提示:
一旦将属性的数据类型更改为uuid,
# db/schema.rb
create_table "lots", id: false, force: :cascade do |t|
#t.string "material_id"
t.uuid "material_id"
end
lot = Lot.new
# trying to assign an integer...
lot.material_id({material_id: 1})
# results in gracious failure
=> nil
# the same is true for 'nearly valid' UUID strings, note the four last chars
lot.material_id = "44ab2cc4-f9e5-45c9-a08d-de6a98c0xxxx"
=> nil
但是,您仍然会得到正确的验证响应:
lot.valid?
=> false
lot.errors.messages
=> {:material_id=>["is not a valid UUID"]}
5条答案
按热度按时间p8h8hvxi1#
基于使用regex的普遍建议:
请注意,这只检查字符串是否符合
8-4-4-4-12
,并忽略任何版本检查。0vvn1miw2#
虽然我的回答会稍微限制问题的概括性,但我希望它仍然足够有趣。这种限制是假设您根据您想要检查的参数集示例化一个新对象,开始验证,然后返回errors对象,除非nil。
这样你就可以使用Rails内置的验证机制。然而,截至2020年5月,似乎还没有原生支持将属性的格式验证为UUID。我所说的原生,是指沿着这样的东西:
在Rails 6.0.3中键入以下代码,您将得到:
因此,将属性验证为UUID的关键是生成一个UuidValidator类,并确保Rails的内部能够自然地找到并使用它。
受www.example.com的Doug Puchalski提供的coderwall.comsuggested解决方案的启发,结合Rails API docs,我提出了以下解决方案:
现在,假设您示例化了一个新的Lot示例,并错误地将一个整数作为外键分配给material_id:
重要提示:
一旦将属性的数据类型更改为uuid,
Rails 6将自动只接受有效的uuid来赋值给material_id。当试图赋值有效的UUID字符串以外的任何字符串时,它将以优雅的方式失败:
但是,您仍然会得到正确的验证响应:
dluptydi3#
您可以使用gem uuid的
UUID.validate(my_string)
类方法。请访问https://www.rubydoc.info/gems/uuid/2.3.1/UUID#validate-class_method
请注意,它与几种UUID格式匹配。
xfb7svmp4#
使用https://github.com/dpep/rspec-uuid:
然后测试它是否为uuid:
或者,您可以检查特定的UUID版本:
js4nwp545#
使用正则表达式匹配器来验证它,这取决于您验证UUID版本。我相信有很多资源可以用于每个UUID版本的正则表达式模式。